大约8个月前,我使用了一个建议来设置一个保留表,然后按照这个帖子推送到正式表并防止重复输入:Best way to prevent duplicate data on copy csv postgresql
它工作得非常好,但今天我注意到数据中存在一些错误和差距。
这是我得到的错误的一个例子,虽然在下一个chron插页中,它经历了。
我没有注意到数据传入的任何重大变化。以下是现在的数据: 总之,我注意到最近插入语句的奇怪之处,并且成功不稳定,导致数据库中存在大量数据空白。感谢您的帮助,我很乐意提供更多详细信息,但我想知道我的信息是否听起来像是其他人已经处理过的事情。
非常感谢您的帮助, 小号
答案 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);