From e922b0b47276d9af8bfe014a70a1bcc5979772cf Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Thu, 1 Oct 2026 20:19:10 +0800 Subject: [PATCH] =?UTF-8?q?fix(migration):=20089=20=E8=A1=A5=E9=BD=90=20vi?= =?UTF-8?q?ral=5Fvideo=5Fjobs=20storyboard/generated=5Fcopy=5Ftext=20?= =?UTF-8?q?=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _ensure_viral_video_columns backfill 列表中包含 storyboard/generated_copy_text/ voice_id/voice_source/video_ratio/video_model/copy_result 共7列,但之前只有 migration 087 (image_analysis) + 088 (copy_result 等5列),缺 storyboard 和 generated_copy_text 两列;在 AUTO_CREATE_SCHEMA=false 且 _ensure_viral_video_columns 不被调用的环境(staging watchtower重启),SQLAlchemy 读写 viral_video_jobs 会直接 500。本次加 089 幂等补齐全部7列 IF NOT EXISTS,配合 entrypoint 启动时 alembic upgrade head 彻底兜底。 --- .../089_viral_video_storyboard_backfill.py | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 alembic/versions/089_viral_video_storyboard_backfill.py diff --git a/alembic/versions/089_viral_video_storyboard_backfill.py b/alembic/versions/089_viral_video_storyboard_backfill.py new file mode 100644 index 000000000..1f0786919 --- /dev/null +++ b/alembic/versions/089_viral_video_storyboard_backfill.py @@ -0,0 +1,49 @@ +"""viral video add storyboard + generated_copy_text (complement 088) + +Revision ID: 089_viral_video_storyboard_backfill +Revises: 088_viral_video_copy_result +Create Date: 2026-10-01 + +#2129 兜底迁移:补齐 _VIRAL_VIDEO_BACKFILL_COLS 中所有列,覆盖 +# watchtower 自动部署未跑历史 migration、且 AUTO_CREATE_SCHEMA=false 时 +# _ensure_viral_video_columns 未执行的场景。 +# 幂等 ADD COLUMN IF NOT EXISTS,已存在则跳过。 +""" + +import sqlalchemy as sa + +from alembic import op + +revision = "089_viral_video_storyboard_backfill" +down_revision = "088_viral_video_copy_result" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + cols = [ + ("storyboard", "JSON"), + ("generated_copy_text", "TEXT NOT NULL DEFAULT ''"), + ("voice_id", "VARCHAR(200) NOT NULL DEFAULT ''"), + ("voice_source", "VARCHAR(20) NOT NULL DEFAULT ''"), + ("video_ratio", "VARCHAR(10) NOT NULL DEFAULT '9:16'"), + ("video_model", "VARCHAR(100) NOT NULL DEFAULT ''"), + ("copy_result", "JSON"), + ] + conn = op.get_bind() + for name, ddl in cols: + try: + conn.execute(sa.text(f"ALTER TABLE viral_video_jobs ADD COLUMN IF NOT EXISTS {name} {ddl}")) + except Exception: + try: + conn.execute(sa.text(f"ALTER TABLE viral_video_jobs ADD COLUMN {name} {ddl}")) + except Exception: + pass + + +def downgrade() -> None: + for name in ("copy_result", "video_model", "video_ratio", "voice_source", "voice_id", "generated_copy_text", "storyboard"): + try: + op.drop_column("viral_video_jobs", name) + except Exception: + pass