复合外键子集的级联更新
cascading update on subset from composite foreign-keys
我在下面显示了 tables.As,table GridCell
将所有行作为复合主键,它们是 table 中的外键GridCellOpDependentParticular
。 table OpDependentParticular
也是如此。
对于 table GridCell
,geometryOfCellRepresentativeToTreatment
和 geometryOfCellRepresentativeToBuffer
两列的初始值设置为 POLYGON EMPTY
或 010300000000000000
。
创建 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 geometry
和fk_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
我在下面显示了 tables.As,table GridCell
将所有行作为复合主键,它们是 table 中的外键GridCellOpDependentParticular
。 table OpDependentParticular
也是如此。
对于 table GridCell
,geometryOfCellRepresentativeToTreatment
和 geometryOfCellRepresentativeToBuffer
两列的初始值设置为 POLYGON EMPTY
或 010300000000000000
。
创建 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 geometry
和fk_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