- 新增 Announcement 数据模型,支持公告的增删改查 - 后台管理新增"公告管理"Tab(创建/编辑/删除/启用禁用) - 客户端 /api/announcement 改为从数据库读取 - 账号服务重构,新增无感换号、自动分析等功能 - 新增后台任务调度器、数据库迁移脚本 - Schema/Service/Config 全面升级至 v2.1 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
70 lines
2.2 KiB
Python
70 lines
2.2 KiB
Python
"""
|
|
数据库迁移脚本
|
|
执行: python run_migration.py
|
|
"""
|
|
import os
|
|
import sys
|
|
|
|
# 添加项目路径
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
from sqlalchemy import text
|
|
from app.database import engine, Base
|
|
from app.models.models import CursorAccount, ActivationKey, KeyDevice, UsageLog, GlobalSettings
|
|
|
|
def run_migration():
|
|
"""执行数据库迁移"""
|
|
print("=" * 50)
|
|
print("蜂鸟Pro v2.1 数据库迁移")
|
|
print("=" * 50)
|
|
|
|
# 方式1: 使用 SQLAlchemy 自动创建/更新表结构
|
|
print("\n[1/3] 创建/更新表结构...")
|
|
try:
|
|
Base.metadata.create_all(bind=engine)
|
|
print("✓ 表结构更新完成")
|
|
except Exception as e:
|
|
print(f"✗ 表结构更新失败: {e}")
|
|
return False
|
|
|
|
# 方式2: 执行自定义迁移 SQL
|
|
print("\n[2/3] 执行数据迁移...")
|
|
migration_sqls = [
|
|
# 更新旧的状态值
|
|
"UPDATE cursor_accounts SET status = 'available' WHERE status = 'active'",
|
|
"UPDATE cursor_accounts SET status = 'exhausted' WHERE status = 'expired'",
|
|
# 更新旧的套餐类型
|
|
"UPDATE activation_keys SET membership_type = 'auto' WHERE membership_type = 'free'",
|
|
]
|
|
|
|
with engine.connect() as conn:
|
|
for sql in migration_sqls:
|
|
try:
|
|
conn.execute(text(sql))
|
|
conn.commit()
|
|
print(f"✓ {sql[:50]}...")
|
|
except Exception as e:
|
|
# 忽略不存在的列/值错误
|
|
if "Unknown column" not in str(e) and "Data truncated" not in str(e):
|
|
print(f"⚠ 跳过: {e}")
|
|
|
|
# 方式3: 初始化默认设置
|
|
print("\n[3/3] 初始化全局设置...")
|
|
try:
|
|
from sqlalchemy.orm import Session
|
|
with Session(engine) as db:
|
|
from app.services import GlobalSettingsService
|
|
GlobalSettingsService.init_settings(db)
|
|
print("✓ 全局设置初始化完成")
|
|
except Exception as e:
|
|
print(f"⚠ 设置初始化: {e}")
|
|
|
|
print("\n" + "=" * 50)
|
|
print("迁移完成!")
|
|
print("=" * 50)
|
|
print("\n现在可以启动后端: uvicorn app.main:app --reload")
|
|
return True
|
|
|
|
if __name__ == "__main__":
|
|
run_migration()
|