__init__.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. """
  2. @author: luojunhui
  3. """
  4. import pymysql
  5. from contextlib import contextmanager
  6. from applications.exception import QueryError, TransactionError
  7. class DatabaseConnector:
  8. """
  9. 数据库连接器,使用 pymysql 进行 MySQL 数据库操作。
  10. """
  11. def __init__(self, db_config):
  12. """
  13. 初始化数据库连接配置。
  14. :param db_config:
  15. """
  16. self.db_config = db_config
  17. self.connection = None
  18. def connect(self):
  19. """
  20. 建立数据库连接。
  21. :raises ConnectionError: 如果无法连接到数据库。
  22. """
  23. try:
  24. self.connection = pymysql.connect(
  25. host=self.db_config.get("host", "localhost"),
  26. user=self.db_config["user"],
  27. password=self.db_config["password"],
  28. db=self.db_config["db"],
  29. port=self.db_config.get("port", 3306),
  30. charset=self.db_config.get("charset", "utf8mb4"),
  31. )
  32. except pymysql.MySQLError as e:
  33. raise ConnectionError(f"无法连接到数据库: {e}")
  34. def close(self):
  35. """
  36. 关闭数据库连接。
  37. """
  38. if self.connection:
  39. self.connection.close()
  40. self.connection = None
  41. def fetch(self, query, cursor_type=None, params=None):
  42. """
  43. 执行单条查询语句,并返回结果。
  44. :param params: 查询传参
  45. :param cursor_type: 输出的返回格式
  46. :param query: 查询语句
  47. :return: 查询结果列表
  48. :raises QueryError: 如果执行查询时出错。
  49. """
  50. if not self.connection:
  51. self.connect()
  52. try:
  53. with self.connection.cursor(cursor_type) as cursor:
  54. if params:
  55. cursor.execute(query, params)
  56. else:
  57. cursor.execute(query)
  58. result = cursor.fetchall()
  59. return result
  60. except pymysql.MySQLError as e:
  61. self.rollback()
  62. raise QueryError(e, query)
  63. def save(self, query, params):
  64. """
  65. 执行单条插入、更新语句
  66. :param query:
  67. :param params:
  68. :return:
  69. """
  70. if not self.connection:
  71. self.connect()
  72. try:
  73. with self.connection.cursor() as cursor:
  74. affected_rows = cursor.execute(query, params)
  75. if affected_rows:
  76. self.commit()
  77. return affected_rows
  78. else:
  79. self.rollback()
  80. return 0
  81. except pymysql.MySQLError as e:
  82. self.rollback()
  83. raise QueryError(e, query)
  84. def save_many(self, query, params_list):
  85. """
  86. 执行多条查询语句
  87. :param query: SQL 查询语句。
  88. :param params_list: 包含多个参数的列表。
  89. :raises QueryError: 如果执行查询时出错。
  90. """
  91. if not self.connection:
  92. self.connect()
  93. try:
  94. with self.connection.cursor() as cursor:
  95. affected_rows = cursor.executemany(query, params_list)
  96. if affected_rows:
  97. self.commit()
  98. return affected_rows
  99. else:
  100. self.rollback()
  101. return 0
  102. except pymysql.MySQLError as e:
  103. self.rollback()
  104. raise QueryError(e, query)
  105. def commit(self):
  106. """
  107. 提交当前事务。
  108. :raises TransactionError: 如果提交事务时出错。
  109. """
  110. if not self.connection:
  111. raise TransactionError("没有活动的数据库连接。")
  112. try:
  113. self.connection.commit()
  114. except pymysql.MySQLError as e:
  115. self.connection.rollback()
  116. raise TransactionError(f"提交事务失败: {e}")
  117. def rollback(self):
  118. """
  119. 回滚当前事务。
  120. :raises TransactionError: 如果回滚事务时出错。
  121. """
  122. if not self.connection:
  123. raise TransactionError("没有活动的数据库连接。")
  124. try:
  125. self.connection.rollback()
  126. except pymysql.MySQLError as e:
  127. raise TransactionError(f"回滚事务失败: {e}")
  128. @contextmanager
  129. def transaction(self):
  130. """
  131. 上下文管理器,用于处理事务
  132. """
  133. try:
  134. yield self.commit()
  135. except Exception as e:
  136. self.rollback()
  137. raise e
  138. def __enter__(self):
  139. """
  140. 支持 with 语句,进入上下文时建立连接。
  141. """
  142. self.connect()
  143. return self
  144. def __exit__(self, exc_type, exc_val, exc_tb):
  145. """
  146. 支持 with 语句,退出上下文时关闭连接。
  147. """
  148. if exc_type:
  149. self.rollback()
  150. self.close()