为什么这个规则不能防止重复密钥违规?
(postgresql)我试图将 csv 数据复制到表中,但遇到重复的密钥违规错误,并且无法告诉 COPY 忽略这些错误,因此遵循互联网我尝试添加这条规则:
CREATE OR REPLACE RULE ignore_duplicate_inserts AS
ON INSERT TO mytable
WHERE (EXISTS ( SELECT mytable.id
FROM mytable
WHERE mytable.id = new.id)) DO NOTHING;
来规避问题,但我仍然遇到这些错误 - 有什么想法吗?
(postgresql) I was trying to COPY
csv data into a table but I was getting duplicate key violation errors, and there's no way to tell COPY
to ignore those, so following internet wisdom I tried adding this rule:
CREATE OR REPLACE RULE ignore_duplicate_inserts AS
ON INSERT TO mytable
WHERE (EXISTS ( SELECT mytable.id
FROM mytable
WHERE mytable.id = new.id)) DO NOTHING;
to circumvent the problem, but I still get those errors - any ideas why ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
默认规则将内容添加到当前操作:
但是 INSTEAD 规则允许您替换操作:
所以,我认为你想要指定 INSTEAD:
没有 INSTEAD ,当您想说“而不是插入,什么都不做”时,您的规则本质上是说“执行插入,然后什么也不做”,并且据我所知,
DO INSTEAD NOTHING
会这样做。我不是 PostgreSQL 规则方面的专家,但我认为添加“INSTEAD”应该可行。
更新:感谢 araqnid 我们知道:
,因此规则在这种情况下不起作用。但是,触发器在 COPY FROM 期间被触发,因此您可以编写 BEFORE INSERT 触发器当检测到重复行时将返回 NULL:
也就是说,我认为你最好使用 araqnid 的“将其全部加载到临时表中,清理它,并将其复制到最终目的地”对于像你这样的批量加载操作来说是一个更明智的解决方案。
Rules by default add things to the current action:
But an INSTEAD rule allows you to replace the action:
So, I think you want to specify INSTEAD:
Without the INSTEAD, your rule is essentially saying "do the INSERT and then do nothing" when you want to say "instead of the INSERT, do nothing" and, AFAIK, the
DO INSTEAD NOTHING
will do that.I'm not an expert on PostgreSQL rules but I think adding the "INSTEAD" should work.
UPDATE: Thanks to araqnid we know that:
So a rule isn't going to work in this situation. However, triggers are fired during COPY FROM so you could write a BEFORE INSERT trigger that would return NULL when it detected duplicate rows:
That said, I think you'd be better off with araqnid's "load it all into a temporary table, clean it up, and copy it to the final destination" would be a more sensible solution for a bulk loading operation like you have.
COPY FROM
不会调用规则(http://www.postgresql.org/docs/9.0/interactive/sql-copy.html#AEN58860)我的方法是将 CSV 数据加载到临时文件中表,然后使用 INSERT...SELECT 语句将数据复制到尚不存在的目标表中。 (如果 CSV 数据本身存在重复项,请先从临时表中删除这些重复项)。像这样的东西:
COPY FROM
will not invoke rules (http://www.postgresql.org/docs/9.0/interactive/sql-copy.html#AEN58860)My approach would be to load the CSV data into a temp table, then use an
INSERT...SELECT
statement to copy the data into the target table where it doesn't already exist. (If there are duplicates in the CSV data itself, remove those from the temp table first). Something like: