#!/usr/bin/env python3 """ 数据库迁移脚本 - 添加新字段 """ import asyncio from sqlalchemy import text from app.database import engine async def column_exists(conn, table_name: str, column_name: str) -> bool: """检查列是否存在""" result = await conn.execute(text(f""" SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = '{table_name}' AND COLUMN_NAME = '{column_name}' """)) count = result.scalar() return count > 0 async def add_column_if_not_exists(conn, table_name: str, column_name: str, column_def: str): """如果列不存在则添加""" if not await column_exists(conn, table_name, column_name): sql = f"ALTER TABLE {table_name} ADD COLUMN {column_name} {column_def}" print(f"添加字段: {column_name}...") await conn.execute(text(sql)) print(f"✓ {column_name} 添加成功") else: print(f"○ {column_name} 已存在,跳过") async def migrate(): """添加新字段到 app_info 表""" print("=" * 60) print("开始数据库迁移...") print("=" * 60) migrations = [ # (列名, 列定义) ("dev_id", "VARCHAR(100)"), ("supplier", "VARCHAR(255)"), ("kind_id", "VARCHAR(50)"), ("tag_name", "VARCHAR(100)"), ("price", "VARCHAR(50) DEFAULT '0'"), ("main_device_codes", "JSON"), ("target_sdk", "VARCHAR(50)"), ("min_sdk", "VARCHAR(50)"), ("compile_sdk_version", "INT"), ("min_hmos_api_level", "INT"), ("api_release_type", "VARCHAR(50) DEFAULT 'Release'"), ("ctype", "INT"), ("app_level", "INT"), ("packing_type", "INT"), ] async with engine.begin() as conn: for column_name, column_def in migrations: try: await add_column_if_not_exists(conn, "app_info", column_name, column_def) except Exception as e: print(f"✗ {column_name} 失败: {e}") print("\n" + "=" * 60) print("数据库迁移完成!") print("=" * 60) async def run_migration(): """运行迁移并清理""" try: await migrate() finally: await engine.dispose() if __name__ == "__main__": asyncio.run(run_migration())