init_toolbox_data.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. """
  2. 百宝箱数据库迁移脚本
  3. 执行百宝箱相关的SQL迁移文件
  4. 从.env文件读取数据库连接信息
  5. """
  6. import os
  7. import sys
  8. from pathlib import Path
  9. from dotenv import load_dotenv
  10. import psycopg2
  11. from psycopg2 import sql
  12. # 添加项目根目录到路径
  13. sys.path.insert(0, str(Path(__file__).parent.parent))
  14. # 加载环境变量
  15. env_path = Path(__file__).parent.parent / '.env'
  16. load_dotenv(dotenv_path=env_path)
  17. def get_db_connection():
  18. """从环境变量获取数据库连接"""
  19. try:
  20. conn = psycopg2.connect(
  21. host=os.getenv("DB_HOST", "localhost"),
  22. port=int(os.getenv("DB_PORT", "5432")),
  23. database=os.getenv("DB_NAME", "aigcspace"),
  24. user=os.getenv("DB_USER", "postgres"),
  25. password=os.getenv("DB_PASSWORD", "")
  26. )
  27. return conn
  28. except Exception as e:
  29. print(f"❌ 数据库连接失败: {e}")
  30. sys.exit(1)
  31. def execute_sql_file(cursor, file_path: Path):
  32. """执行SQL文件"""
  33. try:
  34. with open(file_path, 'r', encoding='utf-8') as f:
  35. sql_content = f.read()
  36. # 执行SQL
  37. cursor.execute(sql_content)
  38. print(f"✓ 执行成功: {file_path.name}")
  39. return True
  40. except Exception as e:
  41. print(f"❌ 执行失败: {file_path.name}")
  42. print(f" 错误信息: {e}")
  43. return False
  44. def verify_data(cursor):
  45. """验证数据是否正确插入"""
  46. try:
  47. # 查询总数
  48. cursor.execute("SELECT COUNT(*) FROM aigcspace.toolbox_apps;")
  49. total = cursor.fetchone()[0]
  50. print(f"\n📊 数据验证:")
  51. print(f" 总应用数: {total}")
  52. # 按分类统计
  53. cursor.execute("""
  54. SELECT category, COUNT(*) as count
  55. FROM aigcspace.toolbox_apps
  56. WHERE status = 'active'
  57. GROUP BY category
  58. ORDER BY count DESC;
  59. """)
  60. print(f"\n 分类分布:")
  61. for row in cursor.fetchall():
  62. print(f" - {row[0]}: {row[1]}个")
  63. # 显示所有应用
  64. cursor.execute("""
  65. SELECT app_key, name, category, is_new, version
  66. FROM aigcspace.toolbox_apps
  67. ORDER BY sort_order DESC;
  68. """)
  69. print(f"\n 应用列表:")
  70. for row in cursor.fetchall():
  71. app_key, name, category, is_new, version = row
  72. new_tag = " [New]" if is_new else ""
  73. version_tag = f" ({version})" if version else ""
  74. print(f" - {name}{new_tag}{version_tag} - {category}")
  75. return True
  76. except Exception as e:
  77. print(f"❌ 数据验证失败: {e}")
  78. return False
  79. def main():
  80. """主函数"""
  81. print("=" * 60)
  82. print("百宝箱数据库迁移脚本")
  83. print("=" * 60)
  84. # 获取迁移文件路径
  85. migrations_dir = Path(__file__).parent.parent / 'migrations'
  86. migration_files = [
  87. migrations_dir / '034_create_toolbox_apps_table.sql',
  88. migrations_dir / '035_init_toolbox_apps_data.sql'
  89. ]
  90. # 检查文件是否存在
  91. for file_path in migration_files:
  92. if not file_path.exists():
  93. print(f"❌ 迁移文件不存在: {file_path}")
  94. sys.exit(1)
  95. print(f"\n📁 找到 {len(migration_files)} 个迁移文件")
  96. for file_path in migration_files:
  97. print(f" - {file_path.name}")
  98. # 连接数据库
  99. print(f"\n🔌 连接数据库...")
  100. print(f" Host: {os.getenv('DB_HOST', 'localhost')}")
  101. print(f" Port: {os.getenv('DB_PORT', '5432')}")
  102. print(f" Database: {os.getenv('DB_NAME', 'aigcspace')}")
  103. print(f" User: {os.getenv('DB_USER', 'postgres')}")
  104. conn = get_db_connection()
  105. cursor = conn.cursor()
  106. print(f"✓ 数据库连接成功")
  107. # 执行迁移文件
  108. print(f"\n🚀 开始执行迁移...")
  109. success_count = 0
  110. for file_path in migration_files:
  111. if execute_sql_file(cursor, file_path):
  112. success_count += 1
  113. else:
  114. # 如果执行失败,回滚并退出
  115. conn.rollback()
  116. cursor.close()
  117. conn.close()
  118. print(f"\n❌ 迁移失败,已回滚所有更改")
  119. sys.exit(1)
  120. # 提交事务
  121. conn.commit()
  122. print(f"\n✓ 所有迁移执行成功 ({success_count}/{len(migration_files)})")
  123. # 验证数据
  124. verify_data(cursor)
  125. # 关闭连接
  126. cursor.close()
  127. conn.close()
  128. print(f"\n" + "=" * 60)
  129. print("✅ 百宝箱数据库迁移完成!")
  130. print("=" * 60)
  131. print(f"\n💡 下一步:")
  132. print(f" 1. 启动后端服务: cd backend && python main.py")
  133. print(f" 2. 启动前端服务: cd frontend && npm run dev")
  134. print(f" 3. 访问页面: http://localhost:5173/toolbox")
  135. print()
  136. if __name__ == "__main__":
  137. try:
  138. main()
  139. except KeyboardInterrupt:
  140. print(f"\n\n⚠️ 用户中断执行")
  141. sys.exit(1)
  142. except Exception as e:
  143. print(f"\n\n❌ 执行过程中发生错误: {e}")
  144. import traceback
  145. traceback.print_exc()
  146. sys.exit(1)