【问题标题】:cascading update on subset from composite foreign-keys从复合外键对子集进行级联更新
【发布时间】:2022-01-09 18:17:43
【问题描述】:

我有下面发布的表。如图所示,表GridCell 的所有行都作为复合主键,它们是表GridCellOpDependentParticular 中的外键。这同样适用于表OpDependentParticular。 对于表GridCellgeometryOfCellRepresentativeToTreatmentgeometryOfCellRepresentativeToBuffer 两列的初始值设置为POLYGON EMPTY010300000000000000。 创建表后,我将更新后两列如下:

sql = '''
        UPDATE GridCell set 
            geometryOfCellRepresentativeToTreatment = ST_GeomFromGeoJSON(fourCornersOfKeyWindowRepresentativeToTreatmentAsGeoJSON)
        WHERE 
            geometryOfCellRepresentativeToTreatment = 'POLYGON EMPTY' and fourCornersOfKeyWindowRepresentativeToTreatmentAsGeoJSON <> '' and fourCornersOfKeyWindowRepresentativeToTreatmentAsGeoJSON IS NOT NULL;

        UPDATE GridCell SET
            geometryOfCellRepresentativeToBuffer = ST_GeomFromGeoJSON(fourCornersOfKeyWindowRepresentativeToBufferAsGeoJSON)
        WHERE 
           geometryOfCellRepresentativeToBuffer = 'POLYGON EMPTY' and fourCornersOfKeyWindowRepresentativeToBufferAsGeoJSON <> '' and fourCornersOfKeyWindowRepresentativeToBufferAsGeoJSON IS NOT NULL;
        '''.format()
    self.cur.execute(sql)
    self.conn.commit()

我想要实现的是使表GridCellOpDependentParticular 中的两列fk_gridCell_geometryOfCellRepresentativeToTreatment geometryfk_gridCell_geometryOfCellRepresentativeToBuffer geometry 在我执行后自动更新 上述更新语句。

我搜索了答案,但没有找到仅更新复合外键中的某些列而不指定所有外键的答案

代码

create table if not exists GridCell(
    fourCornersOfKeyWindowRepresentativeToTreatmentAsGeoJSON jsonb,
    fourCornersOfKeyWindowRepresentativeToBufferAsGeoJSON jsonb,
    geometryOfCellRepresentativeToTreatment geometry,
    geometryOfCellRepresentativeToBuffer geometry,
    fk_site_selectedSiteID text,
    fk_OpIndependentParticular_isTreatment boolean,
    fk_OpIndependentParticular_isBuffer boolean,
    fk_OpIndependentParticular_distanceFromCPOfTreatmentToNearestEdge float8,
    fk_OpIndependentParticular_distanceFromCPOfBufferToNearestEdge float8,
    foreign key (fk_site_selectedSiteID) references Site(selectedSiteID),
    foreign key (fk_OpIndependentParticular_isTreatment,fk_OpIndependentParticular_isBuffer,fk_OpIndependentParticular_distanceFromCPOfTreatmentToNearestEdge,fk_OpIndependentParticular_distanceFromCPOfBufferToNearestEdge) 
        references OpIndependentParticular(isTreatment,isBuffer,distanceFromCPOfTreatmentToNearestEdge,distanceFromCPOfBufferToNearestEdge),
    primary key (fourCornersOfKeyWindowRepresentativeToTreatmentAsGeoJSON,fourCornersOfKeyWindowRepresentativeToBufferAsGeoJSON,geometryOfCellRepresentativeToTreatment,
    geometryOfCellRepresentativeToBuffer,fk_site_selectedSiteID,fk_OpIndependentParticular_isTreatment,fk_OpIndependentParticular_isBuffer,fk_OpIndependentParticular_distanceFromCPOfTreatmentToNearestEdge,
    fk_OpIndependentParticular_distanceFromCPOfBufferToNearestEdge)
    /*
     * UNIQUE (fourCornersOfKeyWindowRepresentativeToTreatmentAsGeoJSON,fourCornersOfKeyWindowRepresentativeToBufferAsGeoJSON,geometryOfCellRepresentativeToTreatment,geometryOfCellRepresentativeToBuffer),
     * UNIQUE (fourCornersOfKeyWindowRepresentativeToTreatmentAsGeoJSON,fourCornersOfKeyWindowRepresentativeToBufferAsGeoJSON,geometryOfCellRepresentativeToTreatment,geometryOfCellRepresentativeToBuffer,fk_site_selectedSiteID),
     * */
)
create table if not exists OpDependentParticular(
    AoCForCellsRepresentativeToTreatment float8,
    AoCForCellsRepresentativeToBuffer float8,
    AvgHPerWindowRepresentativeToTreatment float8,
    AvgHPerWindowRepresentativeToBuffer float8,
    primary key(AoCForCellsRepresentativeToTreatment,AoCForCellsRepresentativeToBuffer,AvgHPerWindowRepresentativeToTreatment,
    AvgHPerWindowRepresentativeToBuffer)
)
create table if not exists GridCellOpDependentParticular(
    fk_gridCell_fourCornersOfKeyWindowRepresentativeToTreatmentAsGeoJSON jsonb,
    fk_gridCell_fourCornersOfKeyWindowRepresentativeToBufferAsGeoJSON jsonb,
    fk_gridCell_geometryOfCellRepresentativeToTreatment geometry,
    fk_gridCell_geometryOfCellRepresentativeToBuffer geometry,
    fk_gridCell_fk_site_selectedSiteID text,
    fk_gridCell_fk_OpIndependentParticular_isTreatment boolean,
    fk_gridCell_fk_OpIndependentParticular_isBuffer boolean,
    fk_gridCell_fk_OpIndependentParticular_distanceFromCPOfTreatmentToNearestEdge float8,
    fk_gridCell_fk_OpIndependentParticular_distanceFromCPOfBufferToNearestEdge float8,
    foreign key (fk_gridCell_fourCornersOfKeyWindowRepresentativeToTreatmentAsGeoJSON,fk_gridCell_fourCornersOfKeyWindowRepresentativeToBufferAsGeoJSON,
    fk_gridCell_geometryOfCellRepresentativeToTreatment,fk_gridCell_geometryOfCellRepresentativeToBuffer,fk_gridCell_fk_site_selectedSiteID,
    fk_gridCell_fk_OpIndependentParticular_isTreatment,fk_gridCell_fk_OpIndependentParticular_isBuffer,fk_gridCell_fk_OpIndependentParticular_distanceFromCPOfTreatmentToNearestEdge,
    fk_gridCell_fk_OpIndependentParticular_distanceFromCPOfBufferToNearestEdge) references GridCell(fourCornersOfKeyWindowRepresentativeToTreatmentAsGeoJSON,
    fourCornersOfKeyWindowRepresentativeToBufferAsGeoJSON,geometryOfCellRepresentativeToTreatment,geometryOfCellRepresentativeToBuffer,fk_site_selectedSiteID,fk_OpIndependentParticular_isTreatment,
    fk_OpIndependentParticular_isBuffer,fk_OpIndependentParticular_distanceFromCPOfTreatmentToNearestEdge,fk_OpIndependentParticular_distanceFromCPOfBufferToNearestEdge),
    
    fk_OpDependentParticular_AoCForCellsRepresentativeToTreatment float8,
    fk_OpDependentParticular_AoCForCellsRepresentativeToBuffer float8,
    fk_OpDependentParticular_AvgHPerWindowRepresentativeToTreatment float8,
    fk_OpDependentParticular_AvgHPerWindowRepresentativeToBuffer float8,
    foreign key (fk_OpDependentParticular_AoCForCellsRepresentativeToTreatment,fk_OpDependentParticular_AoCForCellsRepresentativeToBuffer,
    fk_OpDependentParticular_AvgHPerWindowRepresentativeToTreatment,fk_OpDependentParticular_AvgHPerWindowRepresentativeToBuffer) references OpDependentParticular(
    AoCForCellsRepresentativeToTreatment,AoCForCellsRepresentativeToBuffer,AvgHPerWindowRepresentativeToTreatment,AvgHPerWindowRepresentativeToBuffer),
    
    primary key (fk_gridCell_fourCornersOfKeyWindowRepresentativeToTreatmentAsGeoJSON,fk_gridCell_fourCornersOfKeyWindowRepresentativeToBufferAsGeoJSON,
    fk_gridCell_geometryOfCellRepresentativeToTreatment,fk_gridCell_geometryOfCellRepresentativeToBuffer,fk_gridCell_fk_site_selectedSiteID,fk_gridCell_fk_OpIndependentParticular_isTreatment,
    fk_gridCell_fk_OpIndependentParticular_isBuffer,fk_gridCell_fk_OpIndependentParticular_distanceFromCPOfTreatmentToNearestEdge,
    fk_gridCell_fk_OpIndependentParticular_distanceFromCPOfBufferToNearestEdge,fk_OpDependentParticular_AoCForCellsRepresentativeToTreatment,fk_OpDependentParticular_AoCForCellsRepresentativeToBuffer,
    fk_OpDependentParticular_AvgHPerWindowRepresentativeToTreatment,fk_OpDependentParticular_AvgHPerWindowRepresentativeToBuffer)
);

【问题讨论】:

    标签: postgresql foreign-keys postgis composite-primary-key


    【解决方案1】:

    您要查找的是FOREIGN KEY ... ON UPDATE CASCADE。考虑这个表t1,记录如下:

    CREATE TABLE t1 (
      gid int,
      geom geometry(point,4326) DEFAULT 'POINT EMPTY',
      PRIMARY KEY (gid,geom)
    );
    
    INSERT INTO t1 VALUES (42,'POINT(1 1)');
    

    现在在表t2 上创建一个外键,但这次将其声明为ON UPDATE CASCADE

    CREATE TABLE t2 (
      gid int PRIMARY KEY,
      t1_gid int,
      t1_geom geometry(point,4326),
      FOREIGN KEY (t1_gid,t1_geom) 
        REFERENCES t1 (gid,geom)
        ON UPDATE CASCADE
    );
    
    INSERT INTO t2 VALUES (0,42,'POINT(1 1)');
    

    现在,如果您更改 t1 上的复合主键(或其一部分)的值 ...

    UPDATE t1 SET gid = 1
    WHERE gid = 42;
    

    ...它会直接反映在t2:

    SELECT gid,t1_gid,ST_AsText(t1_geom) FROM t2;
    
     gid | t1_gid | st_astext  
    -----+--------+------------
       0 |      1 | POINT(1 1)
    

    演示:db&lt;&gt;fiddle

    【讨论】:

    • 是的,如果我理解正确的话,在我的例子中,外键是复合的——超过 2 个列——而要在级联上更新的只是复合主键中的两列。 .现在更清楚了吗?!
    • @LetsamrIt 您的外键REFERENCE 中的列可以完全更改ON UPDATE CASCADE,否则目标表在外表中将没有可引用的记录。 PK 和 FK 必须相同。如果您的用例另有建议,您需要删除 FK 并查看触发器。
    • @LetsamrIt 如果您的意思是外部表上的更新可以是部分的,我的方法将起作用。检查这个db<>fiddle
    • 谢谢,我会在测试后确认..感谢它
    猜你喜欢
    • 2018-08-05
    • 1970-01-01
    • 2014-01-17
    • 2023-03-09
    • 2015-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多