Fix _upsert_post savepoint: add() inside begin_nested()
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 57s

begin_nested() auto-flushes on entry which triggers the INSERT before
the savepoint is active. Move sess.add() inside the savepoint block
and split into update vs insert paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
giles
2026-02-21 22:59:54 +00:00
parent 9d6a458115
commit 507200893d

View File

@@ -214,23 +214,26 @@ async def _upsert_post(sess: AsyncSession, gp: Dict[str, Any], author_map: Dict[
res = await sess.execute(select(Post).where(Post.ghost_id == gp["id"]))
obj = res.scalar_one_or_none()
if obj is None:
obj = Post(ghost_id=gp["id"]) # type: ignore[call-arg]
sess.add(obj)
_apply_ghost_fields(obj, gp, author_map, tag_map)
try:
async with sess.begin_nested():
await sess.flush()
except IntegrityError:
# Race condition: another request inserted this ghost_id concurrently.
# Expunge the failed object, re-select the existing row, and update it.
sess.expunge(obj)
res = await sess.execute(select(Post).where(Post.ghost_id == gp["id"]))
obj = res.scalar_one()
if obj is not None:
# Row exists — just update
_apply_ghost_fields(obj, gp, author_map, tag_map)
await sess.flush()
else:
# Row doesn't exist — try to insert within a savepoint
obj = Post(ghost_id=gp["id"]) # type: ignore[call-arg]
try:
async with sess.begin_nested():
sess.add(obj)
_apply_ghost_fields(obj, gp, author_map, tag_map)
await sess.flush()
except IntegrityError:
# Race condition: another request inserted this ghost_id.
# Savepoint rolled back; re-select and update.
res = await sess.execute(select(Post).where(Post.ghost_id == gp["id"]))
obj = res.scalar_one()
_apply_ghost_fields(obj, gp, author_map, tag_map)
await sess.flush()
# Backfill user_id from primary author email if not already set
if obj.user_id is None and obj.primary_author_id is not None: