Postgresql插件停止工作,重复键值违规

时间:2016-04-12 01:45:22

标签: postgresql indexing postgis unique-constraint

大约8个月前,我使用了一个建议来设置一个保留表,然后按照这个帖子推送到正式表并防止重复输入:Best way to prevent duplicate data on copy csv postgresql

它工作得非常好,但今天我注意到数据中存在一些错误和差距。

这是我的插入声明: insert statement

以下是索引的设置方式: indexes

这是我得到的错误的一个例子,虽然在下一个chron插页中,它经历了。error

这是好的: success

我没有注意到数据传入的任何重大变化。以下是现在的数据: data looks like 总之,我注意到最近插入语句的奇怪之处,并且成功不稳定,导致数据库中存在大量数据空白。感谢您的帮助,我很乐意提供更多详细信息,但我想知道我的信息是否听起来像是其他人已经处理过的事情。

非常感谢您的帮助, 小号

1 个答案:

答案 0 :(得分:0)

正如戈登在his answer to your previous question中指出的那样,这种方法只有在您拥有对表的独占访问权限时才有效。存在检查和插入本身之间存在延迟,如果另一个进程在此窗口期间修改了表,则最终可能会出现重复项。

如果您使用Postgres 9.5+,最好的方法是跳过存在检查,只需使用INSERT ... ON CONFLICT DO NOTHING语句。

在早期版本中,最简单的解决方案(如果您能负担得起)将在导入期间lock the table。否则,您可以使用循环和异常处理程序模拟ON CONFLICT DO NOTHING(尽管效率较低):

DO $$
DECLARE r RECORD;
BEGIN
  FOR r IN (SELECT * FROM holding) LOOP
    BEGIN
      INSERT INTO ltg_data (pulsecount, intensity, time, lon, lat, ltg_geom)
      VALUES (r.pulsecount, r.intensity, r.time, r.lon, r.lat, r.ltg_geom);
    EXCEPTION WHEN unique_violation THEN
    END;
  END LOOP;
END
$$

顺便说一句,DELETE FROM holding是耗时的,可能是不必要的。将您的临时表创建为TEMP,并在会话结束时自动清理。您可以轻松地构建一个与导入目标的结构相匹配的表:

CREATE TEMP TABLE holding (LIKE ltg_data);