我在PostgreSQL 9.4中创建了很多具有外键的migrations.
这让人头疼,因为在迁移表时,它们必须按照外键所期望的顺序.如果我必须从我的新迁移所依赖的外键的其他包中运行迁移,它会变得更加棘手.
在MySQL中,我可以通过简单地在迁移文件的顶部添加SET FOREIGN_KEY_CHECKS = 0;
来简化这一点.我如何在PostgresSQL中仅针对迁移代码的长度临时执行此操作?
顺便说一句,使用Laravel Schema Builder实现这一点.
我在PostgreSQL 9.4中创建了很多具有外键的migrations.
这让人头疼,因为在迁移表时,它们必须按照外键所期望的顺序.如果我必须从我的新迁移所依赖的外键的其他包中运行迁移,它会变得更加棘手.
在MySQL中,我可以通过简单地在迁移文件的顶部添加SET FOREIGN_KEY_CHECKS = 0;
来简化这一点.我如何在PostgresSQL中仅针对迁移代码的长度临时执行此操作?
顺便说一句,使用Laravel Schema Builder实现这一点.
PostgreSQL不支持任何配置选项,但还有另一种可能性.
postgres=# \d b
Table "public.b"
┌────────┬─────────┬───────────┐
│ Column │ Type │ Modifiers │
╞════════╪═════════╪═══════════╡
│ id │ integer │ │
└────────┴─────────┴───────────┘
Foreign-key constraints:
"b_id_fkey" FOREIGN KEY (id) REFERENCES a(id) DEFERRABLE
Postgres中的引用完整性是通过触发器实现的,您可以在表上禁用触发器.使用这种方法,您可以上传任何数据(风险),但速度要快得多,因为对 Big Data 的判断非常昂贵.如果你的上传是安全的,那么你可以这样做.
BEGIN;
ALTER TABLE b DISABLE TRIGGER ALL;
-- now the RI over table b is disabled
ALTER TABLE b ENABLE TRIGGER ALL;
COMMIT;
下一种可能性是使用延迟约束.此移动约束判断用于提交时间.所以你不应该用INSERT
条命令来遵守秩序:
ALTER TABLE b ALTER CONSTRAINT b_id_fkey DEFERRABLE;
BEGIN
postgres=# SET CONSTRAINTS b_id_fkey DEFERRED;
SET CONSTRAINTS
postgres=# INSERT INTO b VALUES(100); -- this is not in a table
INSERT 0 1
postgres=# INSERT INTO b VALUES(10);
INSERT 0 1
postgres=# COMMIT;
ERROR: insert or update on table "b" violates foreign key constraint "b_id_fkey"
DETAIL: Key (id)=(100) is not present in table "a".
您应该首选这种方法,因为插入的数据将被判断.