簡體   English   中英

Python peewee,使用EXCLUDED解決沖突解決

[英]Python peewee, using EXCLUDED to resolve conflict resolution

我正在嘗試使用此處顯示的語法插入一條記錄。

from peewee import EXCLUDED
query = (MyTable.insert(
    id=sched.id,
    idenc=sched.idenc,
    createdon=sched.createdon,
    modifiedon=sched.modifiedon,
    deletedon=sched.deletedon,
    canceledon=sched.canceledon,
    is_deleted=sched.is_deleted,
    start_date=sched.start_date,
    end_date=sched.end_date,
    label=sched.label
)
    .on_conflict(conflict_target=[MyTable.id,
                                  MyTable.start_date,
                                  MyTable.end_date],
                 update={
                     MyTable.modifiedon: EXCLUDED.modifiedon,
                     MyTable.label: EXCLUDED.label
    },
    where=(EXCLUDED.modifiedon > MyTable.modifiedon)))
query.execute()

這個想法是更新條目,如果它是最新的,其中modifiedon是一個包含時間戳的varchar字段,例如: 2022-11-22T17:00:34.965Z

這將創建如下所示的 sql 語句,

(
    'INSERT INTO "mytable" ("id", "idenc", "createdon", "modifiedon", "deletedon", "canceledon", "isdeleted", "startdate", "enddate", "label") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT ("id", "startdate", "enddate") DO UPDATE SET "modifiedon" = EXCLUDED."modifiedon", "label" = EXCLUDED."label" WHERE
     (EXCLUDED."modifiedon" > "mytable"."modifiedon")',
    [ 'ymmqzHviWsMgabzPTEKU',
    'ebbe37ec-cb75-5bc6-9466-b170a458c469',
    '2022-11-22T17:00:05.175Z',
    '2022-12-05T11:23:31.563569Z',
    '',
    'None',
    False,
    '2022-11-21T18:01:00.000Z',
    '2022-12-31T17:59:00.000Z',
    '1' ]
)

但這什么都不做,也不會拋出異常。 直接在 MySQL 上運行查詢會引發語法錯誤。

任何的想法?

[編輯]

要向上下文添加更多內容,我如何使用 where 條件插入一行。 在這里,主鍵是composite(id,start_date, end_date) ,所以當數據庫中已經有modifiedon的條目時,我如何確保我沒有覆蓋最新的條目?

從理論上講,在非主鍵上帶有WHERE子句的INSERT/REPLACE peewee可以嗎?

目前我正在做的是,

item_existing, created = MyTable.get_or_create()
if not created:
 if item_existing.modifiedon < item.modifiedon:
   Mytable.replace()

但這很容易出現競爭條件。 還有什么好的方法可以解決這個問題嗎?

PS:數據庫引擎:5.7.mysql_aurora.2.08.3

MySQL 不支持指定沖突目標,也不支持EXCLUDED,也不支持WHERE子句。 這在某種程度上也取決於您使用的是 MySQL 還是 MariaDB,因為它們略有不同,但關鍵是您的選擇有限,只能選擇更新某些值。

嘗試使用這些 API 應該引發異常,因此您可能使用的是舊版本的 Peewee。

基本上,對於 MySQL,您可以選擇保留將要插入的數據(例如,用保留中列出的列的數據覆蓋現有數據),或者您可以使用完全不同的值更新某些列。

插入一行的示例,如果它已經存在,則只需對其“修改”應用更改:

(Table
 .insert({'created': now(), 'modified': now(), 'name': 'Something'})
 .on_conflict(preserve=[Table.modified])
 .execute())

插入一行的示例,如果它已經存在,則將其“修改”設置為完全不同的內容:

(Table
 .insert({'created': now(), 'modified': now(), 'name': 'Something'})
 .on_conflict(update={Table.modified: something_totally_different()})
 .execute())

暫無
暫無

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

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