我有一项任务是为来自不同表的一批条目实现“回滚”(不是通常的回滚)功能。例如:
def rollback(cursor, entries):
# entries is a dict of such form:
# {'table_name1': [id1, id2, ...], 'table_name2': [id1, id2, ...], ...}
我需要删除每个table_name中的条目。但是因为这些条目之间可能有一点关系,所以有点复杂。我的想法分几个步骤:
我的问题是:
任何想法和建议都会受到赞赏。
答案 0 :(得分:0)
(1)和(2)不对。很可能会定义列NOT NULL REFERENCES othertable(othercol)
- 在任何正常模式中都有。
我认为您需要做的是对外键依赖关系图进行排序,以找到一个允许您逐个DELETE
排序的顺序,以及需要删除的数据。请注意,由于延迟的外键约束,循环依赖性是可能的,因此您需要降级/忽略DEFERRABLE INITIALLY DEFERRED
约束;你可以暂时违反那些,只要它在COMMIT
时再次保持一致。
即便如此,您可能会遇到问题。如果客户在交易期间使用SET CONSTRAINTS
制作DEFERRABLE INITIALLY IMMEDIATE
约束DEFERRED
,会怎样?那么你就无法应对循环依赖。要处理此问题,您的代码必须[SET CONSTRAINTS ALL DEFERRED
]才能继续。
您需要查看information_schema
或PostgreSQL特定的system catalogs来确定依赖关系。可能值得查看pg_dump
源代码,因为它尝试对转储表进行排序以避免依赖性冲突。你会对pg_constraint
特别感兴趣
目录,或其information_schema
等效information_schema.referential_constraints
,information_schema.constraint_table_usage
和information_schema.constraint_column_usage
。
您可以使用information_schema
或pg_catalog
。不要同时使用两者。 information_schema
是SQL标准且更具可移植性,但查询速度慢,并且没有pg_catalog
包含的所有信息。另一方面,pg_catalog
的架构不能保证在主要版本(例如9.1到9.2)之间保持兼容 - 尽管它通常会这样 - 并且它的使用不可移植。