diff --git a/alembic/versions/095_viral_video_prompt_templates.py b/alembic/versions/095_viral_video_prompt_templates.py index 83a210f11..bc57f66aa 100644 --- a/alembic/versions/095_viral_video_prompt_templates.py +++ b/alembic/versions/095_viral_video_prompt_templates.py @@ -1,7 +1,10 @@ -"""爆款视频 Prompt 模板配置表(#2040) +"""爆款视频 Prompt 模板配置表(#2040)。 + +086 曾预留同名旧表(id varchar / content / variables json),从未被业务使用; +本迁移将其替换为 #2040 新结构。 Revision ID: 095_viral_video_prompt_templates -Revises: 094 +Revises: 094_viral_video_pre_trusted Create Date: 2026-10-04 """ @@ -15,65 +18,85 @@ branch_labels = None depends_on = None +def _table_exists(conn, name: str) -> bool: + return name in sa.inspect(conn).get_table_names() + + def upgrade() -> None: conn = op.get_bind() - inspector = sa.inspect(conn) - if "viral_video_prompt_templates" not in inspector.get_table_names(): - op.create_table( - "viral_video_prompt_templates", - sa.Column("id", sa.Integer, primary_key=True, autoincrement=True), - sa.Column("name", sa.String(128), nullable=False), - sa.Column( - "prompt_type", - sa.String(32), - nullable=False, - ), - sa.Column("version", sa.Integer, nullable=False, server_default="1"), - sa.Column("system_prompt", sa.Text, nullable=False), - sa.Column("user_prompt_template", sa.Text, nullable=False), - sa.Column("example_output", sa.Text, nullable=True), - sa.Column( - "is_active", - sa.Boolean, - nullable=False, - server_default=sa.text("true"), - ), - sa.Column( - "created_at", - sa.DateTime(timezone=True), - server_default=sa.func.now(), - nullable=False, - ), - sa.Column( - "updated_at", - sa.DateTime(timezone=True), - server_default=sa.func.now(), - nullable=False, - ), - ) - op.create_index( - "ix_viral_video_prompt_templates_type_active", - "viral_video_prompt_templates", - ["prompt_type", "is_active"], - ) - op.create_index( - "uq_viral_video_prompt_templates_type_version", - "viral_video_prompt_templates", - ["prompt_type", "version"], - unique=True, - ) + # 086 预留的旧结构表:先删除(无业务数据、无任何引用) + if _table_exists(conn, "viral_video_prompt_templates"): + op.drop_table("viral_video_prompt_templates") + + op.create_table( + "viral_video_prompt_templates", + sa.Column("id", sa.Integer, primary_key=True, autoincrement=True), + sa.Column("name", sa.String(128), nullable=False), + sa.Column("prompt_type", sa.String(32), nullable=False), + sa.Column("version", sa.Integer, nullable=False, server_default="1"), + sa.Column("system_prompt", sa.Text, nullable=False), + sa.Column("user_prompt_template", sa.Text, nullable=False), + sa.Column("example_output", sa.Text, nullable=True), + sa.Column("is_active", sa.Boolean, nullable=False, server_default=sa.text("true")), + sa.Column( + "created_at", + sa.DateTime(timezone=True), + server_default=sa.func.now(), + nullable=False, + ), + sa.Column( + "updated_at", + sa.DateTime(timezone=True), + server_default=sa.func.now(), + nullable=False, + ), + ) + op.create_index( + "ix_vvpt_type_active", + "viral_video_prompt_templates", + ["prompt_type", "is_active"], + ) + op.create_index( + "uq_vvpt_type_version", + "viral_video_prompt_templates", + ["prompt_type", "version"], + unique=True, + ) def downgrade() -> None: conn = op.get_bind() - inspector = sa.inspect(conn) - if "viral_video_prompt_templates" in inspector.get_table_names(): - op.drop_index( - "uq_viral_video_prompt_templates_type_version", - table_name="viral_video_prompt_templates", - ) - op.drop_index( - "ix_viral_video_prompt_templates_type_active", - table_name="viral_video_prompt_templates", - ) + if _table_exists(conn, "viral_video_prompt_templates"): + op.drop_index("uq_vvpt_type_version", table_name="viral_video_prompt_templates") + op.drop_index("ix_vvpt_type_active", table_name="viral_video_prompt_templates") op.drop_table("viral_video_prompt_templates") + + # 恢复 086 的旧预留结构 + op.create_table( + "viral_video_prompt_templates", + sa.Column("id", sa.String(36), primary_key=True), + sa.Column("prompt_type", sa.String(50), nullable=False, index=True), + sa.Column("name", sa.String(200), nullable=False), + sa.Column("content", sa.Text, nullable=False, server_default=""), + sa.Column("variables", sa.JSON, nullable=False, server_default="[]"), + sa.Column("version", sa.Integer, nullable=False, server_default="1"), + sa.Column( + "is_active", + sa.Boolean, + nullable=False, + server_default=sa.text("true"), + index=True, + ), + sa.Column( + "created_at", + sa.DateTime(timezone=True), + nullable=False, + server_default=sa.func.now(), + ), + sa.Column( + "updated_at", + sa.DateTime(timezone=True), + nullable=False, + server_default=sa.func.now(), + ), + ) diff --git a/packages/adapters/sqlalchemy_impl/models.py b/packages/adapters/sqlalchemy_impl/models.py index 1d27406be..7b3f164c3 100755 --- a/packages/adapters/sqlalchemy_impl/models.py +++ b/packages/adapters/sqlalchemy_impl/models.py @@ -991,16 +991,17 @@ class ViralVideoStyleTemplateModel(Base): class ViralVideoPromptTemplateModel(Base): - """爆款视频 Prompt 模板表(由 #2040 seed)""" + """爆款视频 Prompt 模板表(#2040:纯文本 XML 标签模板,运营可直接编辑)""" __tablename__ = "viral_video_prompt_templates" - id = Column(String(36), primary_key=True) - prompt_type = Column(String(50), nullable=False, index=True) - name = Column(String(200), nullable=False) - content = Column(Text, nullable=False, default="") - variables = Column(JSON, nullable=False, default=list) + id = Column(Integer, primary_key=True, autoincrement=True) + name = Column(String(128), nullable=False) + prompt_type = Column(String(32), nullable=False) version = Column(Integer, nullable=False, default=1) - is_active = Column(Boolean, nullable=False, default=True, index=True) + system_prompt = Column(Text, nullable=False) + user_prompt_template = Column(Text, nullable=False) + example_output = Column(Text, nullable=True) + is_active = Column(Boolean, nullable=False, default=True) created_at = Column(DateTime(timezone=True), nullable=False, default=lambda: datetime.now(UTC)) updated_at = Column(DateTime(timezone=True), nullable=False, default=lambda: datetime.now(UTC)) diff --git a/packages/adapters/sqlalchemy_impl/viral_video_repository.py b/packages/adapters/sqlalchemy_impl/viral_video_repository.py index f7a76b8e5..fdcf03386 100755 --- a/packages/adapters/sqlalchemy_impl/viral_video_repository.py +++ b/packages/adapters/sqlalchemy_impl/viral_video_repository.py @@ -6,7 +6,6 @@ from sqlalchemy.orm import Session from packages.adapters.sqlalchemy_impl.models import ( ViralVideoJobModel, - ViralVideoPromptTemplateModel, ViralVideoStyleTemplateModel, ) from packages.domain.viral_video import ViralVideoJob, ViralVideoStatus @@ -234,31 +233,3 @@ class SQLAlchemyViralVideoStyleTemplateRepository: "style_config": dict(model.style_config) if model.style_config else {}, "is_system": model.is_system, } - - -class SQLAlchemyViralVideoPromptTemplateRepository: - """Prompt 模板仓储(由 #2040 seed,这里只读取)。""" - - def __init__(self, session: Session): - self.session = session - - def get_active_by_type(self, prompt_type: str) -> dict | None: - model = ( - self.session.query(ViralVideoPromptTemplateModel) - .filter( - ViralVideoPromptTemplateModel.prompt_type == prompt_type, - ViralVideoPromptTemplateModel.is_active.is_(True), - ) - .order_by(ViralVideoPromptTemplateModel.version.desc()) - .first() - ) - if model is None: - return None - return { - "id": model.id, - "prompt_type": model.prompt_type, - "name": model.name, - "content": model.content, - "variables": list(model.variables or []), - "version": model.version, - }