Hen*_*gon 8 postgresql copy rules insert duplicates
(postgresql)我试图将COPYcsv数据放入表中,但是我遇到了重复的密钥违规错误,并且没有办法告诉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;
Run Code Online (Sandbox Code Playgroud)
为了避免这个问题,但我仍然得到那些错误 - 任何想法为什么?
mu *_*ort 10
默认情况下,规则会向当前操作添加内容:
粗略地说,当执行给定表上的给定命令时,规则会导致执行其他命令.
但INSTEAD规则允许您替换操作:
或者,INSTEAD规则可以用另一个命令替换给定命令,或者根本不执行命令.
所以,我想你想指定INSTEAD:
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 INSTEAD NOTHING;
Run Code Online (Sandbox Code Playgroud)
如果没有INSTEAD,你的规则基本上就是说"做INSERT然后什么都不做"当你想说"而不是INSERT,什么也不做",AFAIK就是DO INSTEAD NOTHING这样做的.
我不是PostgreSQL规则的专家,但我认为添加"INSTEAD"应该可行.
更新:感谢araqnid,我们知道:
COPY FROM将调用目标表上的任何触发器和检查约束.但是,它不会调用规则
所以规则在这种情况下不会起作用.但是,在COPY FROM期间会触发触发器,因此您可以编写BEFORE INSERT 触发器,当它检测到重复行时将返回NULL:
它可以返回NULL以跳过当前行的操作.这指示执行程序不执行调用触发器的行级操作(插入或修改特定表行).
也就是说,我认为你最好用araqnid"将它全部加载到临时表中,清理它并将其复制到最终目的地"对于像你这样的批量加载操作来说是一个更明智的解决方案.
COPY FROM 不会调用规则(http://www.postgresql.org/docs/9.0/interactive/sql-copy.html#AEN58860)
我的方法是将CSV数据加载到临时表中,然后使用INSERT...SELECT语句将数据复制到目标表中,而目标表尚不存在.(如果CSV数据本身有重复项,请先从临时表中删除它们).就像是:
BEGIN;
CREATE TEMP TABLE stage_data(key_column, data_columns...) ON COMMIT DROP;
\copy stage_data from data.csv with csv header
-- prevent any other updates while we are merging input (omit this if you don't need it)
LOCK target_data IN SHARE ROW EXCLUSIVE MODE;
-- insert into target table
INSERT INTO target_data(key_column, data_columns...)
SELECT key_column, data_columns...
FROM stage_data
WHERE NOT EXISTS (SELECT 1 FROM target_data
WHERE target_data.key_column = stage_data.key_column)
END;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5098 次 |
| 最近记录: |