database_loader.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import mysql.connector
  2. from mysql.connector import errorcode
  3. from .config import settings
  4. from app.core.logger import get_logger
  5. logger = get_logger(__name__)
  6. # 全局的连接池
  7. db_connection_pool = None
  8. def init_database():
  9. """
  10. 初始化数据库:如果数据库或表不存在,则创建它们。
  11. """
  12. logger.info("--- 开始初始化数据库 ---")
  13. # 1. 尝试连接MySQL服务器(不指定数据库)
  14. try:
  15. cnx = mysql.connector.connect(**settings.DATABASE_CONFIG)
  16. cursor = cnx.cursor()
  17. # 2. 创建数据库(如果不存在)
  18. cursor.execute(f"CREATE DATABASE IF NOT EXISTS {settings.DB_NAME} DEFAULT CHARACTER SET 'utf8mb4'")
  19. logger.info(f"数据库 '{settings.DB_NAME}' 已准备就绪。")
  20. # 3. 切换到目标数据库
  21. cnx.database = settings.DB_NAME
  22. # 4. 创建表(如果不存在)
  23. table_description = (
  24. f"CREATE TABLE IF NOT EXISTS `{settings.DB_TABLE_NAME}` ("
  25. " `img_id` INT AUTO_INCREMENT PRIMARY KEY,"
  26. " `img_name` VARCHAR(255) NULL,"
  27. " `img_path` VARCHAR(512) NOT NULL,"
  28. " `img_result_json` JSON NOT NULL,"
  29. " `img_result_json_new` JSON NULL,"
  30. " `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP"
  31. ") ENGINE=InnoDB"
  32. )
  33. cursor.execute(table_description)
  34. logger.info(f"数据表 '{settings.DB_TABLE_NAME}' 已准备就绪。")
  35. except mysql.connector.Error as err:
  36. logger.error(f"数据库初始化失败: {err}")
  37. exit(1) # 初始化失败直接退出程序
  38. finally:
  39. if 'cursor' in locals() and cursor:
  40. cursor.close()
  41. if 'cnx' in locals() and cnx.is_connected():
  42. cnx.close()
  43. logger.info("--- 数据库初始化完成 ---")
  44. def load_database_pool():
  45. """
  46. 在应用启动时创建数据库连接池。
  47. """
  48. global db_connection_pool
  49. if db_connection_pool is None:
  50. logger.info("--- 创建数据库连接池 ---")
  51. try:
  52. db_connection_pool = mysql.connector.pooling.MySQLConnectionPool(
  53. pool_name="mypool",
  54. pool_size=5, # 池中保持的连接数
  55. **settings.DATABASE_CONFIG_WITH_DB
  56. )
  57. logger.info("--- 数据库连接池创建成功 ---")
  58. except mysql.connector.Error as err:
  59. logger.error(f"创建数据库连接池失败: {err}")
  60. exit(1)
  61. def close_database_pool():
  62. """
  63. 在应用关闭时,不需要手动关闭连接池,连接器会自动处理。
  64. 这个函数留作备用。
  65. """
  66. logger.info("--- 数据库连接池将自动关闭 ---")
  67. # --- FastAPI 依赖注入 ---
  68. def get_db_connection():
  69. """
  70. 一个FastAPI依赖项,用于从池中获取数据库连接。
  71. 它确保连接在使用后返回到池中。
  72. """
  73. if db_connection_pool is None:
  74. raise RuntimeError("数据库连接池未初始化")
  75. db_conn = None
  76. try:
  77. db_conn = db_connection_pool.get_connection()
  78. yield db_conn
  79. except mysql.connector.Error as err:
  80. logger.error(f"获取数据库连接失败: {err}")
  81. # 这里可以根据需要抛出HTTPException
  82. finally:
  83. if db_conn and db_conn.is_connected():
  84. db_conn.close()