私はこの記事が見つかるまで、PostgreSQLのIntegrityErrorsと同じ問題で苦労しました。私は次の規則に従うことにしました:オブジェクトがデータベースに存在しない場合は、db.add()またはdb.merge()で主キーを指定しないでください。
ここに私がwberryの意味を理解するために使用した例があります。
# Suppose the next value of rows_id_seq will be 33.
# You run the following code.
db.add(Row(id=35))
# Since you specified a primary key, SQLAlchemy will NOT increment rows_id_seq,
# so the next value of rows_id_seq will still be 33.
db.add(Row())
# The next value of rows_id_seq will be 34
db.add(Row())
# The next value of rows_id_seq will be 35
db.add(Row())
db.query(Row.id).all() # Uh-oh
# (IntegrityError) duplicate key value violates unique constraint "rows_pkey"
# Key (id)=(35) already exists.
ここdb.merge()を用いた例です。
# Suppose the next value of rows_id_seq will be 1.
# You run the following code.
db.merge(Row(id=1))
db.merge(Row(id=2))
db.merge(Row(id=3))
# Since you specified a primary key, SQLAlchemy will NOT increment rows_id_seq,
# so the next value of rows_id_seq will still be 1.
db.merge(Row())
db.query(Row.id).all() # Uh-oh
# (IntegrityError) duplicate key value violates unique constraint "rows_pkey"
# Key (id)=(1) already exists.
wberryが正しいです。マージを使用すると、切断されたオブジェクトまたはオブジェクトが別のセッションから取り込まれます。これらが 'new'オブジェクトであれば、' add'を使う必要があります。 'setval'を使うと、あなたのテーブルにすでに存在しているidとは無関係にシーケンスの現在の値が強制的に更新されます。新しいオブジェクトを追加する前にテーブルデータをクリアしていなければ、 –