我有很多来自MySQL的记录。我按摩了数据,因此它将使用ActiveRecord成功插入到PostgreSQL中。这可以很容易地按行进行插入,即一次一行。这是非常慢我想要批量插入但如果任何行包含无效数据,则会失败。无论如何,我可以实现批量插入,只有无效的行失败而不是整个批量?
答案 0 :(得分:1)
在批量插入(或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)
一个常见的解决方法是将数据导入TEMPORARY
或UNLOGGED
表,没有约束,并且输入中的数据足够虚假,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工具。