导入并覆盖重复行

10

我正在像这样将一些行导入到我的PostgreSQL数据库中:

psql -U postgres import_test < 1432798324_data

我的import_test是我的数据库,1432798324_data文件只是普通文本格式,类似于:

COPY cars FROM stdin;
<row data>
<row data>
...
\.

COPY drivers FROM stdin;
<row data>
<row data>
...
\.

(我从这里的回答中获取了该纯文本文件的格式 here)。

当我导入到空数据库时,此方法运行良好。但是,如果数据库不为空,并且在导入期间发现任何重复行,则会出现错误:

ERROR:  duplicate key value violates unique constraint "car_pkey"

如果有重复的数据,我能否修改导入命令以强制覆盖它们?换句话说,如果我正在导入一行数据并且已经存在具有相同id的行,则希望我的新行可以将其覆盖。

2个回答

10

您可以将数据导入到临时表中。然后,您可以删除在复制新数据之前已经存在的行:

create temporary table import_drivers as select * from drivers limit 0;

copy import_drivers from stdin;

begin transaction;

delete  from drivers
where   id in
        (
        select  id
        from    import_drivers
        );

insert  into drivers
select  *
from    import_drivers;

commit transaction;

这段代码放在我的纯文本文件里吗?我基本上会为每个纯文本中的表格都有一个类似于这样的代码块? - Robert
还有,有没有更有效的方法来做这件事,因为其中一些表有数百万行?这必须将所有行插入2次,对吗? - Robert
在导入之前,我会删除所有需要被覆盖的索引。 - Barney Szabolcs

0

如果你需要经常进行批量导入(比如每天),处理这个问题的一种方法是使用表分区。

你只需要在车辆和司机表中添加一个时间字段。时间字段是导入时的时间。你的主键将不得不改变,变成现有主键和时间字段的二元组。

完成后,你只需删除旧表(如果你使用的是每日计划,则应删除前一天的表),或者在查询中使用max(time_field)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接