Fix _upsert_post savepoint: add() inside begin_nested()
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 57s
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:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user