SQLAlchemyモジュール(SQLではない!)を使用して、python)で一括アップサートを記述しようとしています。
SQLAlchemyの追加で次のエラーが表示されます。
_sqlalchemy.exc.IntegrityError: (IntegrityError) duplicate key value violates unique constraint "posts_pkey"
DETAIL: Key (id)=(TEST1234) already exists.
_
posts
列に主キーを持つid
というテーブルがあります。
この例では、dbに_id=TEST1234
_の行が既にあります。 db.session.add()
をid
を_TEST1234
_に設定して新しい投稿オブジェクトにしようとすると、上記のエラーが発生します。主キーが既に存在する場合、レコードが更新されるという印象を受けました。
主キーのみに基づいてFlask-SQLAlchemyでアップサートするにはどうすればよいですか?簡単な解決策はありますか?
存在しない場合は、常に一致するIDのレコードをチェックして削除し、新しいレコードを挿入できますが、多くの更新を期待していない私の状況では、コストがかかるようです。
SQLAlchemyにはupsert-esque操作があります。
db.session.merge()
このコマンドを見つけた後、アップサートを実行できましたが、バルク「アップサート」ではこの操作が遅いことに注意してください。
別の方法は、アップサートする主キーのリストを取得し、一致するIDについてデータベースを照会することです。
# Imagine that post1, post5, and post1000 are posts objects with ids 1, 5 and 1000 respectively
# The goal is to "upsert" these posts.
# we initialize a dict which maps id to the post object
my_new_posts = {1: post1, 5: post5, 1000: post1000}
for each in posts.query.filter(posts.id.in_(my_new_posts.keys())).all():
# Only merge those posts which already exist in the database
db.session.merge(my_new_posts.pop(each.id))
# Only add those posts which did not exist in the database
db.session.add_all(my_new_posts.values())
# Now we commit our modifications (merges) and inserts (adds) to the database!
db.session.commit()