使用ActiveRecord进行PostgreSQL批量插入

时间:2013-06-07 15:54:11

标签: postgresql activerecord

我有很多来自MySQL的记录。我按摩了数据,因此它将使用ActiveRecord成功插入到PostgreSQL中。这可以很容易地按行进行插入,即一次一行。这是非常慢我想要批量插入但如果任何行包含无效数据,则会失败。无论如何,我可以实现批量插入,只有无效的行失败而不是整个批量?

2 个答案:

答案 0 :(得分:1)

COPY

在批量插入(或psql客户端中的等效\copy)中使用SQL COPY时, 失败不是一个选项 COPY不能跳过非法行。您必须将输入格式与导入的表格相匹配。

如果数据本身(不是装饰器)违反了您的表定义,那么有很多方法可以使这个更宽容。例如:创建一个临时登台表,其中包含text类型的所有列。复制到它,然后在转换为实际数据类型并插入实际目标表之前,使用SQL命令修复违规行。

考虑这个相关的答案:
How to bulk insert only new rows in PostreSQL

或者这个更高级的案例:
"ERROR: extra data after last expected column" when using PostgreSQL COPY

如果 NULL有问题,请暂时从目标表中删除NOT NULL约束。 COPY后修复行,然后恢复约束。如果您无法暂时软化规则,请使用临时表 示例代码:

ALTER TABLE tbl ALTER COLUMN col DROP NOT NULL;
COPY ...
-- repair, like ..
-- UPDATE tbl SET col = 0 WHERE col IS NULL;
ALTER TABLE tbl ALTER COLUMN col SET NOT NULL;

或者您只需修复源表。 COPY会告诉您违规行的编号。使用您喜欢的编辑器并修复它,然后重试。我喜欢使用vim

INSERT

对于 INSERT (如评论),检查NULL值非常简单:

要跳过NULL值的行:

INSERT INTO (col1, ...
SELECT col1, ...
WHERE col1 IS NOT NULL

要插入......而不是NULL值(在我的示例中为空字符串):

INSERT INTO (col1, ...
SELECT COALESCE(col1, ''),  ...

答案 1 :(得分:0)

一个常见的解决方法是将数据导入TEMPORARYUNLOGGED表,没有约束,并且输入中的数据足够虚假,text类型列

然后,您可以对数据执行INSERT INTO ... SELECT次查询,以使用在导入期间清理数据的大查询来填充实际表。您可以使用大量CASE语句。我们的想法是一次性转换数据。

您可以在读取数据时在Ruby中执行许多修复,然后使用COPY ... FROM STDIN将数据推送到PostgreSQL。这可以使用Ruby的Pg gem,参见例如https://bitbucket.org/ged/ruby-pg/src/tip/sample/copyfrom.rb

对于更复杂的情况,请查看Pentaho Kettle或Talend Studio ETL工具。