fix(init_db): await 优先级漏括号——启动迁移自诞生起从未执行成功(事故根因)
has_alembic = await conn.execute(...).scalar() 因 await 优先级低于
属性访问,实际解析为 await (conn.execute(...).scalar())——在协程对象
上调 .scalar() 必抛 AttributeError('coroutine' object has no attribute
'scalar')。启动迁移每次容器启动都在第一行炸掉,再被 except 吞成一行
日志(4a5dc61 已改为 logger.exception)。两行均改为
(await conn.execute(...)).scalar()。
已于生产库实测:主库路径(has_alembic=True→upgrade no-op)与临时
历史库路径(stamp+upgrade)全部跑通,临时库已删除。
至此 2026-09-26 事故根因链闭合:启动迁移从未生效 → prod schema 长期
落后于模型 → 新镜像上线即上传 500(缺 product_id)。
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -35,11 +35,15 @@ async def _run_alembic_migrations() -> None:
|
|||||||
- 既有但无 alembic_version(历史 DB):先 stamp head 基线,再 upgrade(no-op)
|
- 既有但无 alembic_version(历史 DB):先 stamp head 基线,再 upgrade(no-op)
|
||||||
"""
|
"""
|
||||||
async with db_manager.engine.begin() as conn:
|
async with db_manager.engine.begin() as conn:
|
||||||
has_alembic = await conn.execute(text("SELECT to_regclass('public.alembic_version')")).scalar()
|
# 注意括号:await 优先级低于属性访问,await conn.execute(...).scalar()
|
||||||
|
# 实际是 await (conn.execute(...).scalar())——会在协程对象上调 .scalar()
|
||||||
|
# 直接 AttributeError。必须 (await conn.execute(...)).scalar()。
|
||||||
|
# 曾因漏括号让启动迁移自诞生起一次都没跑通过(2026-09-26 事故根因)。
|
||||||
|
has_alembic = (await conn.execute(text("SELECT to_regclass('public.alembic_version')"))).scalar()
|
||||||
if not has_alembic:
|
if not has_alembic:
|
||||||
table_count = await conn.execute(
|
table_count = (await conn.execute(
|
||||||
text("SELECT count(*) FROM information_schema.tables WHERE table_schema='public' AND table_name <> 'alembic_version'")
|
text("SELECT count(*) FROM information_schema.tables WHERE table_schema='public' AND table_name <> 'alembic_version'")
|
||||||
).scalar()
|
)).scalar()
|
||||||
if table_count and table_count > 0:
|
if table_count and table_count > 0:
|
||||||
logger.info("检测到既有 DB 未纳入 alembic 管理,自动 stamp head 作为基线")
|
logger.info("检测到既有 DB 未纳入 alembic 管理,自动 stamp head 作为基线")
|
||||||
await asyncio.to_thread(_alembic_stamp_head)
|
await asyncio.to_thread(_alembic_stamp_head)
|
||||||
|
|||||||
Reference in New Issue
Block a user