0

我的任务是为来自不同表的一批条目实现“回滚”(不是通常的回滚)功能。例如:

def rollback(cursor, entries):
    # entries is a dict of such form: 
    # {'table_name1': [id1, id2, ...], 'table_name2': [id1, id2, ...], ...}

我需要删除每个 table_name 中的条目。但是因为这些条目之间可能有关系所以有点复杂。我的想法分为几个步骤:

  1. 从所有可以为空的表中找出所有列。
  2. 更新所有条目将所有可以为空的列设置为空。在这一步之后应该没有循环依赖(如果没有,我认为它们不能插入到表中)
  3. 找出它们的依赖并进行拓扑排序。
  4. 一一删除。

我的问题是:

  1. 这个想法有意义吗?
  2. 有没有人做过类似的事情?如何?
  3. 如何查询第 3 步的元表?因为我对 postgresql 很陌生。

任何想法和建议将不胜感激。

4

1 回答 1

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 的系统目录来确定依赖关系。也可能值得看一下pg_dump源代码,因为它会尝试对转储表进行排序以避免依赖冲突。您将对pg_constraint 目录或其information_schema等价物特别感兴趣information_schema.referential_constraintsinformation_schema.constraint_table_usage并且information_schema.constraint_column_usage.

您可以使用information_schemapg_catalog。不要同时使用两者。information_schema是 SQL 标准且更便携,但查询速度可能很慢,并且没有包含所有信息pg_catalog。另一方面,pg_catalog不保证 ' 架构在主要版本(如 9.1 到 9.2)之间保持兼容——尽管它通常是这样的——而且它的使用是不可移植的。

于 2012-10-15T11:10:05.160 回答