2011-11-01 157 views
0

我试图使用SQL脚本来恢复数据库SQL脚本来恢复数据库,但事情外键约束的方式从外键约束

我正在一个MySQL数据库,并把它交给PostgreSQL的获得。 由于MySQL创建表语法结束了很大的不同,我带了另一个PostgreSQL数据库具有相同的模式,但不同的数据,并从中恢复模式。 换句话说,我现在有一个数据库,其中包含表格,约束,序列以及所有那些内部没有数据的数据库。

因此,现在是恢复数据的时候了。 我使用phpMyAdmin(仅数据)作为SQL脚本备份MySQL数据库(由于某种原因,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多个序列插入语句。所以,我在这里很懒,但是有没有更简单的方法来处理序列呢?

或者,你们对不同的工具有什么建议可以使这更简单吗?

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

+0

mysql有一个'foreign_key_checks'设置,您可以为导入目的禁用 - 不禁用它们就不可能导入任何带有循环引用的表,或者以非常特定的顺序列出表。 PG应该有类似的东西。 –

+0

这些可能有所帮助: 1. http://stackoverflow.com/questions/2679854/postgresql-disabling-constraints,2. http://www.postgresql.org/docs/8.2/static/sql-set-constraints。 html – Abhay

回答

2

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

首先看看约束条件,并确保按正确的顺序插入表格。如果_entity是“_account”的父项,那么它应该先填充。

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

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

我会尝试为PostgreSQL找到一个数据导入工具 - 我住在SQL服务器世界中,我将使用SSIS,但是您需要相当于PostgreSQL世界的SSIS。

+0

哈哈谢谢,是的,最后,我只是移动桌子,所以他们按顺序填充。 – zermy

+0

看看这个http://kettle.pentaho.com/上的免费工具。 – Kuberchaun

2

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

如果它是“唯一”的顺序错误,我看到了两个可能的解决方案:

  1. 编辑生成的脚本,要么将所有FK定义的脚本
  2. 编辑每个FK的定义结束约束并将它们全部设置为initially deferred。然后将脚本作为一个单独的事务运行,仅在最后提交。

编辑(因为这是过多地放在一个评论)

使用SET CONSTRAINTS ALL DEFERRED如果约束已经与选项DEFERRABLE创建才起作用。

要在单个事务中运行所有事务,您必须确保已关闭自动提交。然后只需运行INSERT,最后发出COMMIT。 A ;只会在您自动提交时才会提交。

如果您希望独立于自动提交设置,请使用[BEGIN][1]开始您的脚本,并确保最后只有一个COMMIT。

BEGIN DEFERRABLE 
    INSERT INTO table_one ... ; 
    INSERT INTO table_two ... ; 
    ..... 
COMMIT; 
+0

约束定义不是我正在运行的查询的一部分。表和约束已经创建。 按照Abhay的建议,我试着在开头添加这行代码来运行查询:SET CONSTRAINTS ALL DEFERRED;但它不起作用,我认为这是因为有很多提交。我是否正确地假设每次用';'结束查询,然后查询都被提交?如果是的话,我怎么才能最终承诺? 感谢您的回复。 – zermy

+0

非常感谢您的帮助,但不幸的是,我不认为约束是使用可延迟选项创建的,所以,我只是继续前进,并围绕插入顺序移动。 – zermy