migrate_add_qq_unionid.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. """
  2. 数据库迁移脚本:为 users 表添加 qq_unionid 字段
  3. 运行: python migrate_add_qq_unionid.py
  4. """
  5. import asyncio
  6. import sys
  7. import aiomysql
  8. from config import settings
  9. async def migrate_add_qq_unionid():
  10. """为 users 表添加 qq_unionid 字段"""
  11. conn = None
  12. try:
  13. conn = await aiomysql.connect(
  14. host=settings.MYSQL_HOST,
  15. port=settings.MYSQL_PORT,
  16. user=settings.MYSQL_USER,
  17. password=settings.MYSQL_PASSWORD,
  18. db=settings.MYSQL_DATABASE,
  19. charset="utf8mb4",
  20. )
  21. async with conn.cursor() as cursor:
  22. # 检查 users 表是否存在
  23. await cursor.execute(
  24. """
  25. SELECT COUNT(*)
  26. FROM information_schema.tables
  27. WHERE table_schema = %s AND table_name = 'users'
  28. """,
  29. (settings.MYSQL_DATABASE,),
  30. )
  31. table_exists = (await cursor.fetchone())[0] > 0
  32. if not table_exists:
  33. print("❌ users 表不存在,请先创建表")
  34. await conn.ensure_closed()
  35. return False
  36. # 检查是否已存在 qq_unionid 列
  37. await cursor.execute(
  38. """
  39. SELECT COUNT(*)
  40. FROM information_schema.columns
  41. WHERE table_schema = %s
  42. AND table_name = 'users'
  43. AND column_name = 'qq_unionid'
  44. """,
  45. (settings.MYSQL_DATABASE,),
  46. )
  47. has_unionid = (await cursor.fetchone())[0] > 0
  48. if has_unionid:
  49. print("✅ qq_unionid 字段已存在,无需迁移")
  50. await conn.ensure_closed()
  51. return True
  52. print("🔄 添加 qq_unionid 字段...")
  53. await cursor.execute(
  54. """
  55. ALTER TABLE users
  56. ADD COLUMN qq_unionid VARCHAR(128) UNIQUE NULL COMMENT 'QQ UnionID'
  57. AFTER qq_openid
  58. """
  59. )
  60. await cursor.execute(
  61. """
  62. CREATE INDEX idx_qq_unionid ON users(qq_unionid)
  63. """
  64. )
  65. await conn.commit()
  66. print("✅ qq_unionid 字段添加成功")
  67. await conn.ensure_closed()
  68. return True
  69. except Exception as exc:
  70. import traceback
  71. print(f"❌ 迁移失败: {exc}")
  72. traceback.print_exc()
  73. if conn and not conn.closed:
  74. await conn.ensure_closed()
  75. return False
  76. if __name__ == "__main__":
  77. if len(sys.argv) > 1 and sys.argv[1] == "--force":
  78. confirm = "y"
  79. else:
  80. confirm = input("\n是否继续迁移 users 表添加 qq_unionid 字段? (y/n): ")
  81. if confirm.lower() != "y":
  82. sys.exit(0)
  83. success = asyncio.run(migrate_add_qq_unionid())
  84. if not success:
  85. sys.exit(1)