簡體   English   中英

無法更新 PostgreSQL 與 Psycopg2 沖突的現有行

[英]Cannot update existing row on conflict in PostgreSQL with Psycopg2

我定義了以下 function 以使用 Psycopg2 和 PostgreSQL 11 在 Python 中插入幾行迭代。當我收到相同的 obj.

def insert_execute_values_iterator(
    connection,
    objs: Iterator[Dict[str, Any]],
    page_size: int = 1000,
) -> None:
    with connection.cursor() as cursor:
        try:
            psycopg2.extras.execute_values(cursor, """
                INSERT INTO objs(\
                                                id,\
                                                date,\
                ) VALUES %s \
                ON CONFLICT (id) \
                    DO UPDATE SET (date) = (EXCLUDED.date) \
            """, ((
                obj['id'],
                obj['date'],

            ) for obj in objs), page_size=page_size)
        except (Exception, Error) as error:
            print("Error while inserting as in database", error)

當插入元素時表的唯一主鍵發生沖突時,我收到錯誤消息:

在數據庫中插入時出錯 ON CONFLICT DO UPDATE 命令不能再次影響行 提示:確保在同一命令中建議插入的行沒有重復的約束值。

僅供參考,該條款直接適用於 PostgreSQL,但不適用於 Python 代碼。

在 INSERT 語句中使用唯一的 VALUE 組合:

create table foo(id int primary key, date date);

這應該有效:

INSERT INTO foo(id, date) 
VALUES(1,'2021-02-17') 
ON CONFLICT(id) 
DO UPDATE SET date = excluded.date;

這個不會:

INSERT INTO foo(id, date) 
VALUES(1,'2021-02-17') , (1, '2021-02-16') -- 2 conflicting rows
ON CONFLICT(id) 
DO UPDATE SET date = excluded.date;

演示

您可以通過在 SELECT 語句中使用 DISTINCT ON() 來解決此問題:

INSERT INTO foo(id, date) 
SELECT DISTINCT ON(id) id, date
FROM (VALUES(1,CAST('2021-02-17' AS date)) , (1, '2021-02-16')) s(id, date)
ORDER BY id, date ASC
ON CONFLICT(id) 
DO UPDATE SET date = excluded.date;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM