概要
PostgresqlでUPSERTを使う準備についての備忘録
UPSERT は ON CONFLICT ON CONSTRAINT を利用して実行します。
ここで指定した一意制約などの制約に違反した場合にINSERTからUPDATEに処理を切り替えることで実装します。
制約を確認する
ここで利用する(エラーを起こしたい)テーブルの制約を確認します。
select table_name, constraint_name, constraint_type from information_schema.table_constraints where table_name='テーブル名'
こちらで確認してUNIQUE制約があれば constraint_name を控えておいてください。
table_name | constraint_name | constraint_type
------------+----------------------------+-----------------
tableA | tableA_pkey | PRIMARY KEY
tableA | tableA_unique_id_key | UNIQUE
制約を作る
UNIQUE制約がなければ制約を作らなければなりません。
ここで多くの方が迷ってしまうと思いますが、PostgresqlではUNIQUE制約とUNIQUEインデックスは別物ということです。
UPSERTを使う場合はUNIQUEインデックスではなくUNIQUE制約がなければなりません。
制約を作るのは簡単です。ALTER TABLEでPRIMARY KEYを作るときと同じです。
alter table table名 add unique(column名);
こちらを実行したら「制約を確認する」の手順でUNIQUE制約のconstraint_nameを確認してください。
実際にUPSERTする
実際にUPSERTするSQLは以下です。
制約名は先ほど控えた制約名を指定してください。
insert into テーブル名(column名) values(値...)
ON CONFLICT ON CONSTRAINT 制約名
DO
UPDATE SET column名=値
DOの後にUPDATE文を書けばいいですがこの場合、table名も条件も必要ありません。
insert into テーブル名(column名) values(値...)
ON CONFLICT ON CONSTRAINT 制約名
DO NOTHING
この様にDOの後にNOTHINGをつければ一意制約違反を無視することができます。
例外を受けて一意制約だったら無視の様な処理を作らなくてもよいのでコーディングも処理負荷も楽になります。
オススメです。