我需要在每次触发单元测试时删除所有表中的所有数据。现在我正在使用
对于测试套件中包含的每个表,TRUNCATE TABLE "table_name" CASCADE
。
问题是那些查询需要花费很多时间 - 大约9-11秒!
我希望能够用TRUNCATE...CASCADE
语句替换那些TRUNCATE
,但为了做到这一点,我需要一个按主 - 细节(父 - 子)关系排序的表列表(子项)第一)。手动我可以创建一次或两次这样的列表,但数据库每天都会更改。有没有办法按顺序生成表格列表?
我正在使用Postgresql。
答案 0 :(得分:1)
我想解决这个问题的方法如下:
推迟所有可延迟约束并忽略它们。你不能在不可延迟的外键中有效地拥有循环,因为没有插入顺序可以满足它们
我会构建一个存储过程,它会查找可延迟的外键并将它们全部推迟。这是相对微不足道的。
我会构建一个CTE,它将构建一个外键约束树,然后通过它们搜索它们按照到达它们的路径的长度来反转顺序,这样第一个表就是那些最有用的表。桌子取决于他们的钥匙。
然而,这可能是矫枉过正的。只有两个函数可能更容易:
函数1查看类中的每个关系以及每个关系,问题:
EXECUTE $e$ ALTER TABLE $e$ || quote_ident(relname) || $e$ disable trigger all $e$;
功能2反过来:
EXECUTE $e$ ALTER TABLE $e$ || quote_ident(relname) || $e$ enable trigger all $e$;
在清除过程开始时调用功能1。在提交之前调用函数2.