【问题标题】:Import and overwrite duplicate rows导入和覆盖重复行
【发布时间】:2015-08-10 14:34:24
【问题描述】:

我正在将一些行导入到我的 postgres 数据库中,如下所示:

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,我希望我的新行覆盖它。

【问题讨论】:

    标签: postgresql import duplicates overwrite psql


    【解决方案1】:

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

    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;
    

    【讨论】:

    • 所以这段代码在我的纯文本文件中?对于我的纯文本中的每个表,我基本上都会有一大块这样的代码?
    • 另外,有没有更有效的方法来做到这一点,因为其中一些表有数百万行?这必须将所有行插入 2 次对吗?
    • 我会在导入之前删除所有需要覆盖的索引。
    【解决方案2】:

    在您不断进行批量导入(比如说每天)的情况下,解决此问题的一种方法是使用表分区。

    您只需在您的汽车和司机表中添加一个时间字段。时间字段是您进行导入的时间。您必须将两个表的主键更改为现有主键和时间字段的两个元组。

    完成后,您只需删除旧表(如果您使用的是每日方案,那么您将删除前一天),或者在查询中使用 max(time_field)

    【讨论】:

      猜你喜欢
      • 2021-11-10
      • 2014-06-15
      • 2018-03-28
      • 2012-02-16
      • 1970-01-01
      • 2015-04-16
      • 1970-01-01
      • 1970-01-01
      • 2023-01-19
      相关资源
      最近更新 更多