导入/更新PostgreSQL中的现有行

时间:2009-05-15 05:25:19

标签: postgresql

我正在开发一个爱好应用程序,它将包含大量基本上硬编码的数据,以及部署后的动态用户数据。我希望能够在本地更新硬编码数据(比UPDATE更多INSERT s),然后将这些数据导出到服务器。换句话说,我需要将数据转储到文件中,并以新行(相对较少)为INSERT的方式导入,并且现有行(由PK标识)为{ {1}} d。显然,新行不能在服务器上UPDATE(或者PK可能会发生冲突并发出错误的INSERT s);这是一个可接受的限制。但是,我不能UPDATE行为DELETE d,更不用说删除同步表,因为用户可访问的表将对“静态”表具有FK约束。

不幸的是,这似乎很难做到。谷歌和Postgres邮件列表告诉我,“类似MySQL的”功能UPDATE“将在新版本中”(陈旧信息;是否存在?),以及“on_duplicate_key_update”的建议,没有迹象如何

在最糟糕的情况下,我想我可以提出一个home-brewn解决方案(转储数据文件,编写一个自定义导入脚本来检查PK冲突和问题pg_loader can do it或{{1} }适当的声明),但对于其他人在我面前遇到的问题,这似乎是一个非常笨拙的解决方案。

有什么想法吗?

4 个答案:

答案 0 :(得分:2)

是的,临时表+插入/更新的一些组合是要走的路(你不需要在函数中执行它,但你可以)。

对于记录,您要查找的功能是Merge命令。有人为它写了一个补丁,但它从未完成。 AFAIK现在没有人正在研究它;它肯定不会在即将发布的Postgres 8.4中发布。

答案 1 :(得分:0)

您是否考虑过在本地运行postgresql?

  1. 转储服务器数据
  2. 本地导入
  3. 启用查询记录
  4. 进行更新
  5. 获取查询日志并在服务器上运行
  6. 清除查询日志
  7. 或者我误解了你想要做的事情?

答案 2 :(得分:0)

create temporary table newdata as select * from table1 where false;

使用新数据填写新数据,然后:

start transaction;
create function fill_table1() returns void as
$$
declare
    data record;
begin
    for data in select * from newdata
    loop
        update table1 set
            column1 = data.column1,
            column2 = data.column2
        where id = data.id
        if not found then
            insert into table1 values data.*;
        end if;
    end loop;
end;
$$ language plpgsql;
select fill_table();
drop function fill_table();
commit;

这未经过测试,因此可能需要进行一些调整才能正常工作。它要求表在运行时不会改变。

答案 3 :(得分:0)

此问题与this类似:

也许您可以查看我在那里提供的解决方案。