2016-12-05 68 views
0

我正在執行以下代碼,但偶爾會發生重複密鑰違規,並且整個插入操作都會停止。如何忽略這些錯誤並讓查詢對有效條目執行?psycopg2在多行插入時忽略重複密鑰違規

代碼:

query_data = ','.join(cur.mogrify('(%s,%s)', row) for row in data) 
insert_q = "INSERT INTO <table> VALUES {0};".format(query_data) 

try: 
    cur.execute(insert_q)      
except psycopg2.Error: 
    self.logger.exception('Database error') 

con.commit() 

更新2:

我貼我自己的答案下面這解決了這個問題。它在Postgres中使用新的ON CONFLICT語法。

更新1:

有一個關於內commiting除了塊,但是,我發現,問題,如果你沒有其他所有刀片將不執行給以下錯誤:

ERROR: current transaction is aborted, commands ignored until end of transaction block 

爲了避免混淆,增加當您在提交except塊的嘗試後提交除

+0

這是不是你做的在查詢中。這是您在創建表格時設置的東西(或者可以通過更改表格來實現)。 – 2016-12-05 20:55:52

+1

另外,你爲什麼要在'except'塊內執行? – 2016-12-05 20:56:39

+0

如果你不這樣做,所有其他的查詢都不會被執行。這只是代碼的一個示例。 – c00der

回答

1

,通常整個腳本將阻止。

編輯,解釋更詳細:

try: 
    cur.execute(insert_q)      
    con.commit() 
except psycopg2.Error: 
    self.logger.exception('Database error') 
    con.rollback() 
+0

我不知道你是否閱讀這個問題。這絕對不是答案。這就是我所不知道的。 – c00der

+0

謝謝,但回滾會跳過整個批量插入。如果我批量插入10,000行,並且如果一行違反了唯一約束,則不會插入所有行。這就是我需要的答案。讓其中一行插入時忽略。 – c00der

+0

Python端:您可以在插入之前驗證您的數據,Postgres端:通過存儲過程插入,執行約束檢查(跳過插入) –

0

以下是工作的代碼(與查詢):

query_data = ','.join(cur.mogrify('(%s,%s)', row) for row in data) 
insert_q = "INSERT INTO <table> VALUES {0} ON CONFLICT DO NOTHING;".format(query_data) 

try: 
    cur.execute(insert_q)      
except psycopg2.Error: 
    self.logger.exception('Database error') 

con.commit() 

查找更多關於這個在這裏:What happens with duplicates when inserting multiple rows?