0

我正在尝试使用 SQL 脚本恢复数据库,但是外键约束妨碍了

我正在使用 MySQL DB 并将其带到 PostgreSQL。由于 MySQL 创建表的语法最终完全不同,因此我采用了另一个具有相同架构但数据不同的 PostgreSQL 数据库,并仅从中恢复了架构。换句话说,我现在有一个包含表、约束、序列和所有内容的数据库,但里面没有数据。

所以,是时候恢复数据了。我使用 phpMyAdmin(仅数据)备份 MySQL DB 作为 SQL 脚本(由于某种原因,pgAdmin 似乎不接受 zip 或 gzip 文件)并运行 SQL 脚本。现在,这就是问题开始发生的地方,这是很自然的,我从 MySQL 转到 PostgreSQL,所以必然会发生语法错误。

但是,还有其他与语法无关的问题,例如:

ERROR: insert or update on table "_account" violates foreign key constraint "fk_1_account"
DETAIL:  Key (accountid)=(2) is not present in table "_entity".

所以,是的,基本上,存在外部约束,查询正在尝试将数据插入_account表中,但相应的数据尚未插入_entity表中。我该如何解决?有没有办法让 pgAdmin3/PostgreSQL 禁用所有约束,插入数据,然后重新启用约束?

我遇到的一个与语法相关的错误是:

 INSERT INTO _accounttype_seq (id) VALUES (11);

该语句的 PostgreSQL 等效项(如果我是正确的)是

 ALTER SEQUENCE _accounttype_seq INCREMENT BY 11; 

但是,运行整个脚本并更改所有 200 多个序列插入语句有点痛苦。所以,我在这里很懒,但是还有更简单的方法来处理序列吗?

或者,你们对一组不同的工具有什么建议可以使这更容易吗?

感谢您的时间,祝您有美好的一天。

4

2 回答 2

2

显然,外键实际上并没有在 MySQL 中强制执行(可能是因为使用了 MyISAM),或者生成的 SQL 只是以错误的顺序执行。

如果它“仅”是错误的顺序,我会看到两种可能的解决方案:

  1. 编辑生成的脚本并将所有 FK 定义移动到脚本的末尾
  2. 编辑每个 FK 约束的定义并将它们全部设置为initially deferred. 然后将脚本作为一个事务运行,最后只在提交时。

编辑(因为这太多了,不能作为评论)

仅当使用选项创建约束时,使用SET CONSTRAINTS ALL DEFERRED才会起作用DEFERRABLE

要在一个事务中运行所有内容,您必须确保已关闭自动提交。然后只需运行INSERTs 并在最后发出 a COMMIT。A;仅在您启用自动提交时才会提交。

如果你想独立于自动提交设置,那么启动你的脚本[BEGIN][1]并确保最后只有一个 COMMIT。

BEGIN DEFERRABLE
   INSERT INTO table_one ... ;
   INSERT INTO table_two ... ; 
   .....
COMMIT;
于 2011-11-01T17:10:59.743 回答
2

不要试图绕过外键约束。这是确保数据错误的方法。

首先查看约束并确保您以正确的顺序插入到表中。如果 _entity 是“_account”的父级,则应首先填充它。

接下来,您需要让脚本将所有失败的记录移至异常表。然后您可以查看它们并查看数据完整性问题是什么,以及是否需要永久丢弃记录或尝试找出丢失的父值应该是什么。如果它是关键数据,例如客户不再存在的订单(可能在任何没有正确 fks 开始的系统中)并且您必须保留记录并且无法确定父值应该是什么,您可以创建客户表中的“未知”记录,并将所有不良订单分配给该客户 ID。

即使很无聊,手动更改更改序列也不应该花很长时间。在这种类型的转换中,您还需要手动处理许多其他事情。

我会尝试为 PostgreSQL 找到一个数据导入工具——我生活在 SQL 服务器世界中,我会使用 SSIS,但对于 PostgreSQL 世界,你需要与 SSIS 等效的东西。

于 2011-11-01T18:18:58.567 回答