migrate_add_page_visit_logs_table.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. """
  2. 数据库迁移脚本:创建 page_visit_logs 表
  3. 运行: python migrations/migrate_add_page_visit_logs_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_page_visit_logs_table() -> bool:
  11. """创建 page_visit_logs 表(如果不存在)"""
  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. await cursor.execute(
  23. """
  24. SELECT COUNT(*) FROM information_schema.tables
  25. WHERE table_schema = %s AND table_name = 'page_visit_logs'
  26. """,
  27. (settings.MYSQL_DATABASE,),
  28. )
  29. exists_row: Any = await cursor.fetchone()
  30. table_exists = bool(exists_row and exists_row[0] > 0)
  31. if table_exists:
  32. print("✅ page_visit_logs 表已存在,无需迁移")
  33. await conn.ensure_closed()
  34. return True
  35. print("🔄 创建 page_visit_logs 表...")
  36. await cursor.execute(
  37. """
  38. CREATE TABLE page_visit_logs (
  39. id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '主键',
  40. user_id VARCHAR(64) NULL COMMENT '用户ID(未登录则为空)',
  41. path VARCHAR(512) NOT NULL COMMENT '访问路径',
  42. visited_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '访问时间',
  43. INDEX idx_page_visit_user_id (user_id),
  44. INDEX idx_page_visit_path (path(255)),
  45. INDEX idx_page_visit_visited_at (visited_at)
  46. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='页面访问日志表';
  47. """
  48. )
  49. await conn.commit()
  50. print("✅ page_visit_logs 表创建完成")
  51. await conn.ensure_closed()
  52. return True
  53. except Exception as exc: # noqa: BLE001
  54. import traceback
  55. print(f"❌ 迁移失败: {exc}")
  56. traceback.print_exc()
  57. return False
  58. if __name__ == "__main__":
  59. if len(sys.argv) > 1 and sys.argv[1] == "--force":
  60. confirm = "y"
  61. else:
  62. confirm = input("\n是否继续创建 page_visit_logs 表? (y/n): ")
  63. if confirm.lower() != "y":
  64. sys.exit(0)
  65. ok = asyncio.run(migrate_create_page_visit_logs_table())
  66. if not ok:
  67. sys.exit(1)