4
我有一個表在ETL例程中一次填充一列。 強制性列(其是外鍵)首先被設置,並在一次,所以表中的初始狀態爲:什麼時候運行NOT NULL約束,並且能等到事務要提交?
key | fkey | a
-------|--------|-------
1 | 1 | null
處理的值後,我將它們插入使用SQL鍊金PostgreSQL的方言一個簡單的UPSERT:
upsert = sqlalchemy.sql.text("""
INSERT INTO table
(key, a)
VALUES (:key, :a)
ON CONFLICT (key) DO UPDATE SET
a = EXCLUDED.a
""")
但這種失敗,因爲它顯然試圖插入fkey
值null
。
psycopg2.IntegrityError: null value in column "fkey" violates not-null constraint
DETAIL: Failing row contains (1, null, 0).
語法是否真的正確?爲什麼失敗? SQLAlchemy對此錯誤有任何參與嗎?或者它是否正確地翻譯了PLSQL?
我懷疑是約束檢查發生的衝突解決之前觸發,所以雖然它實際上工作,因爲fkey
是保證之前沒有空,也不會被覆蓋,約束檢查只着眼於暫定插入和表約束。
PS:我知道我可以使用UPDATE而不是INSERT + ON CONFLICT,因爲行保證在那裏。我重複使用舊代碼,只是想知道它爲什麼失敗。 – VillasV
你是對的,postgres評估UPSERT的限制,即使它總是會進入ON CONFLICT部分。你可以用很多方法解決這個問題,比如使用你提到的UPDATE,或者從約束切換到觸發AFTER事件,因爲它不會爲執行ON CONFLICT部分的行觸發。 –