Files
WonderQ-Project/WonderQ-Admin/alembic/versions/0034_media_assets.py
T
duanshuwen 4e04feda5b feat(admin, miniapp): 优化数据库迁移逻辑与小程序图片资源处理
- 为后端Admin新增migration_compat工具,支持离线迁移时的基线资源检查,重构全部alembic迁移脚本适配离线模式,避免重复创建已存在的数据库表和字段
- 完善初始数据库迁移脚本,添加默认部门种子数据,新增ConciergeAdvisor详情字段从JSON到JSONB的类型转换迁移
- 小程序端新增图片资源解析工具resolveNetworkImage,实现本地静态资源到CDN的自动映射,添加图片加载容错降级机制
- 完善HeroSlide类型定义,新增actionLabel字段,优化首页轮播组件的文本渲染与错误处理逻辑
- 新增对应测试用例验证迁移路径正确性与前端数据处理逻辑
- 新增临时 brainstorm UI对比草稿与开发临时状态文件
2026-08-27 11:37:03 +08:00

77 lines
2.3 KiB
Python

"""Create the media asset table required by admin uploads."""
from alembic import context, op
import sqlalchemy as sa
from sqlalchemy import inspect
from app.migration_compat import baseline_table_names
revision = "0034_media_assets"
down_revision = "0033_remove_site_versions"
branch_labels = None
depends_on = None
DEFAULT_DEPT_ID = "00000000-0000-0000-0000-000000000001"
def is_offline_mode() -> bool:
try:
return context.is_offline_mode()
except (NameError, AttributeError):
return False
def _table_names() -> set[str]:
if is_offline_mode():
return baseline_table_names()
return set(inspect(op.get_bind()).get_table_names())
def upgrade() -> None:
if "MediaAsset" in _table_names():
return
op.create_table(
"MediaAsset",
sa.Column("id", sa.String(), nullable=False),
sa.Column("url", sa.String(), nullable=False, unique=True),
sa.Column("name", sa.String(), nullable=True),
sa.Column("mimeType", sa.String(), nullable=True),
sa.Column("sizeBytes", sa.Integer(), nullable=True),
sa.Column("group", sa.String(), nullable=True),
sa.Column(
"deptId",
sa.String(),
nullable=False,
server_default=sa.text(f"'{DEFAULT_DEPT_ID}'"),
),
sa.Column("createdById", sa.String(), nullable=True),
sa.Column("createdAt", sa.DateTime(), nullable=False),
sa.Column("updatedAt", sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(
["deptId"],
["AdminDepartment.id"],
name="fk_MediaAsset_deptId",
ondelete="RESTRICT",
),
sa.ForeignKeyConstraint(
["createdById"],
["AdminUser.id"],
name="fk_MediaAsset_createdById",
ondelete="SET NULL",
),
sa.PrimaryKeyConstraint("id"),
)
op.create_index("ix_MediaAsset_deptId", "MediaAsset", ["deptId"])
op.create_index("ix_MediaAsset_createdById", "MediaAsset", ["createdById"])
def downgrade() -> None:
if "MediaAsset" not in _table_names():
return
op.drop_index("ix_MediaAsset_createdById", table_name="MediaAsset")
op.drop_index("ix_MediaAsset_deptId", table_name="MediaAsset")
op.drop_table("MediaAsset")