Postgres:如何删除多个表中的条目

时间:2012-10-15 10:31:37

标签: postgresql metadata topological-sort

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

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

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

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

    1. 这个想法有意义吗?
    2. 以前有人做过类似的事吗?怎么样?
    3. 如何查询第3步的元表?因为我对postgresql很新。
    4. 任何想法和建议都会受到赞赏。

1 个答案:

答案 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_constraintsinformation_schema.constraint_table_usageinformation_schema.constraint_column_usage

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