migrate_add_verification_codes_table.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. """
  2. 数据库迁移脚本:创建验证码表
  3. 运行: python migrate_add_verification_codes_table.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_create_verification_codes_table() -> bool:
  11. """创建验证码表"""
  12. try:
  13. conn: aiomysql.Connection = 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. # 检查表是否存在
  23. await cursor.execute(
  24. """
  25. SELECT COUNT(*) FROM information_schema.tables
  26. WHERE table_schema = %s AND table_name = 'verification_codes'
  27. """,
  28. (settings.MYSQL_DATABASE,),
  29. )
  30. exists_row: Any = await cursor.fetchone()
  31. table_exists = bool(exists_row and exists_row[0] > 0)
  32. if not table_exists:
  33. print("🔄 创建 verification_codes 表...")
  34. await cursor.execute(
  35. """
  36. CREATE TABLE verification_codes (
  37. id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '主键',
  38. code_id VARCHAR(64) NOT NULL UNIQUE COMMENT '验证码ID',
  39. -- 接收方信息(手机号或邮箱,根据发送类型二选一)
  40. phone VARCHAR(20) NULL COMMENT '手机号',
  41. email VARCHAR(200) NULL COMMENT '邮箱',
  42. -- 验证码信息
  43. code VARCHAR(10) NOT NULL COMMENT '验证码',
  44. send_type ENUM('domestic_sms', 'international_sms', 'email') NOT NULL COMMENT '发送类型:国内短信、国外短信、邮箱',
  45. -- 状态信息
  46. is_sent TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否已发送',
  47. is_valid TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否有效',
  48. -- 时间信息
  49. created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  50. sent_at TIMESTAMP NULL COMMENT '发送时间',
  51. -- 扩展信息
  52. metadata JSON NULL COMMENT '扩展信息(发送结果、错误信息等)',
  53. INDEX idx_code_id (code_id),
  54. INDEX idx_verification_code_phone (phone, is_valid, created_at),
  55. INDEX idx_verification_code_email (email, is_valid, created_at),
  56. INDEX idx_verification_code_send_type (send_type, is_sent, is_valid)
  57. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  58. COMMENT='验证码表'
  59. """
  60. )
  61. await conn.commit()
  62. print("✅ verification_codes 表创建完成")
  63. else:
  64. print("✅ verification_codes 表已存在")
  65. conn.close()
  66. return True
  67. except Exception:
  68. import traceback
  69. traceback.print_exc()
  70. return False
  71. if __name__ == "__main__":
  72. if len(sys.argv) > 1 and sys.argv[1] == "--force":
  73. confirm = "y"
  74. else:
  75. confirm = input("\n是否继续执行迁移? (y/n): ")
  76. if confirm.lower() != "y":
  77. sys.exit(0)
  78. ok = asyncio.run(migrate_create_verification_codes_table())
  79. if not ok:
  80. sys.exit(1)