migrate_add_v2_community_tables.py 4.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. """
  2. V2.0 迁移:创建 user_community_choice、user_early_community 表
  3. 运行: python migrations/migrate_add_v2_community_tables.py
  4. """
  5. import asyncio
  6. import sys
  7. from typing import Any
  8. import aiomysql
  9. from config import settings
  10. async def migrate() -> bool:
  11. try:
  12. conn: aiomysql.Connection = await aiomysql.connect(
  13. host=settings.MYSQL_HOST,
  14. port=settings.MYSQL_PORT,
  15. user=settings.MYSQL_USER,
  16. password=settings.MYSQL_PASSWORD,
  17. db=settings.MYSQL_DATABASE,
  18. charset="utf8mb4",
  19. )
  20. async with conn.cursor() as cursor:
  21. # user_community_choice:退出早期共创社区选项
  22. await cursor.execute(
  23. """
  24. SELECT COUNT(*) FROM information_schema.tables
  25. WHERE table_schema = %s AND table_name = 'user_community_choice'
  26. """,
  27. (settings.MYSQL_DATABASE,),
  28. )
  29. exists = bool((await cursor.fetchone() or [0])[0])
  30. if not exists:
  31. print("🔄 创建 user_community_choice 表...")
  32. await cursor.execute(
  33. """
  34. CREATE TABLE user_community_choice (
  35. id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  36. user_id VARCHAR(64) NOT NULL UNIQUE COMMENT '用户ID',
  37. opted_out BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否选择退出早期共创社区',
  38. updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  39. INDEX idx_user_id (user_id)
  40. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  41. COMMENT='用户是否退出早期共创社区'
  42. """
  43. )
  44. await conn.commit()
  45. print("✅ user_community_choice 表创建完成")
  46. else:
  47. print("✅ user_community_choice 表已存在")
  48. # user_early_community:早期共创邮箱与弹窗状态
  49. await cursor.execute(
  50. """
  51. SELECT COUNT(*) FROM information_schema.tables
  52. WHERE table_schema = %s AND table_name = 'user_early_community'
  53. """,
  54. (settings.MYSQL_DATABASE,),
  55. )
  56. exists2 = bool((await cursor.fetchone() or [0])[0])
  57. if not exists2:
  58. print("🔄 创建 user_early_community 表...")
  59. await cursor.execute(
  60. """
  61. CREATE TABLE user_early_community (
  62. id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  63. user_id VARCHAR(64) NOT NULL UNIQUE COMMENT '用户ID',
  64. email VARCHAR(200) NULL COMMENT '加入早期共创时留的邮箱',
  65. popup_shown BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否已展示过弹窗',
  66. joined_at TIMESTAMP NULL COMMENT '加入时间(留邮箱时)',
  67. created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  68. updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  69. INDEX idx_user_id (user_id)
  70. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  71. COMMENT='用户早期共创社区(手机号新用户留邮箱)'
  72. """
  73. )
  74. await conn.commit()
  75. print("✅ user_early_community 表创建完成")
  76. else:
  77. print("✅ user_early_community 表已存在")
  78. conn.close()
  79. return True
  80. except Exception:
  81. import traceback
  82. traceback.print_exc()
  83. return False
  84. if __name__ == "__main__":
  85. confirm = input("\n是否继续执行迁移? (y/n): ") if len(sys.argv) <= 1 or sys.argv[1] != "--force" else "y"
  86. if confirm.lower() != "y":
  87. sys.exit(0)
  88. ok = asyncio.run(migrate())
  89. sys.exit(0 if ok else 1)