复合外键子集的级联更新

cascading update on subset from composite foreign-keys

我在下面显示了 tables.As,table GridCell 将所有行作为复合主键,它们是 table 中的外键GridCellOpDependentParticular。 table OpDependentParticular 也是如此。 对于 table GridCellgeometryOfCellRepresentativeToTreatmentgeometryOfCellRepresentativeToBuffer 两列的初始值设置为 POLYGON EMPTY010300000000000000。 创建 table 后,我将按如下方式更新后两列:

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()

我想实现的是让tableGridCellOpDependentParticular中的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)
);

您要找的是 FOREIGN KEY ... ON UPDATE CASCADE。使用以下记录考虑此 table 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)');

现在 table 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<>fiddle