MySQLConnection.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. __title__ = 'MySQL连接池对象'
  5. @Time : 2020/9/26 18:36
  6. @Author : Kenny-PC
  7. @Software: PyCharm
  8. # code is far away from bugs with the god animal protecting
  9. I love animals. They taste delicious.
  10. ┏┓ ┏┓
  11. ┏┛┻━━━┛┻┓
  12. ┃ ☃ ┃
  13. ┃ ┳┛ ┗┳ ┃
  14. ┃ ┻ ┃
  15. ┗━┓ ┏━┛
  16. ┃ ┗━━━┓
  17. ┃ 神兽保佑 ┣┓
  18. ┃ 永无BUG! ┏┛
  19. ┗┓┓┏━┳┓┏┛
  20. ┃┫┫ ┃┫┫
  21. ┗┻┛ ┗┻┛
  22. """
  23. """
  24. 数据库连接池相关
  25. """
  26. import configparser
  27. import logging
  28. import os
  29. import pymysql
  30. from DBUtils.PooledDB import PooledDB
  31. # 获取当前文件所在目录的上一级目录
  32. root_dir = os.path.dirname(os.path.abspath('.'))
  33. # print('当前项目根目录为:', root_dir)
  34. # 读取数据库配置信息
  35. config = configparser.ConfigParser()
  36. config.read(root_dir + '/tests/conf/db.ini', encoding='UTF-8')
  37. sections = config.sections()
  38. # 数据库工厂
  39. dbFactory = {}
  40. for dbName in sections:
  41. # 读取相关属性
  42. maxconnections = config.get(dbName, "maxconnections")
  43. mincached = config.get(dbName, "mincached")
  44. maxcached = config.get(dbName, "maxcached")
  45. host = config.get(dbName, "host")
  46. port = config.get(dbName, "port")
  47. user = config.get(dbName, "user")
  48. password = config.get(dbName, "password")
  49. database = config.get(dbName, "database")
  50. databasePooled = PooledDB(creator=pymysql,
  51. maxconnections=int(maxconnections),
  52. mincached=int(mincached),
  53. maxcached=int(maxcached),
  54. blocking=True,
  55. cursorclass=pymysql.cursors.DictCursor,
  56. host=host,
  57. port=int(port),
  58. user=user,
  59. password=password,
  60. database=database)
  61. dbFactory[dbName] = databasePooled
  62. class MySQLConnection(object):
  63. """
  64. 数据库连接池代理对象
  65. 查询参数主要有两种类型
  66. 第一种:传入元祖类型,例如(12,13),这种方式主要是替代SQL语句中的%s展位符号
  67. 第二种: 传入字典类型,例如{"id":13},此时我们的SQL语句需要使用键来代替展位符,例如:%(name)s
  68. """
  69. def __init__(self, dbName="test"):
  70. self.connect = dbFactory[dbName].connection()
  71. self.cursor = self.connect.cursor()
  72. logging.debug("获取数据库连接对象成功,连接池对象:{}".format(str(self.connect)))
  73. def execute(self, sql, param=None):
  74. """
  75. 基础更新、插入、删除操作
  76. :param sql:
  77. :param param:
  78. :return: 受影响的行数
  79. """
  80. ret = None
  81. try:
  82. if param == None:
  83. ret = self.cursor.execute(sql)
  84. else:
  85. ret = self.cursor.execute(sql, param)
  86. except TypeError as te:
  87. logging.debug("类型错误")
  88. logging.exception(te)
  89. return ret
  90. def query(self, sql, param=None):
  91. """
  92. 查询数据库
  93. :param sql: 查询SQL语句
  94. :param param: 参数
  95. :return: 返回集合
  96. """
  97. self.cursor.execute(sql, param)
  98. result = self.cursor.fetchall()
  99. return result
  100. def queryOne(self, sql, param=None):
  101. """
  102. 查询数据返回第一条
  103. :param sql: 查询SQL语句
  104. :param param: 参数
  105. :return: 返回第一条数据的字典
  106. """
  107. result = self.query(sql, param)
  108. if result:
  109. return result[0]
  110. else:
  111. return None
  112. def listByPage(self, sql, current_page, page_size, param=None):
  113. """
  114. 分页查询当前表格数据
  115. :param sql: 查询SQL语句
  116. :param current_page: 当前页码
  117. :param page_size: 页码大小
  118. :param param:参数
  119. :return:
  120. """
  121. countSQL = "select count(*) ct from (" + sql + ") tmp "
  122. logging.debug("统计SQL:{}".format(sql))
  123. countNum = self.count(countSQL, param)
  124. offset = (current_page - 1) * page_size
  125. totalPage = int(countNum / page_size)
  126. if countNum % page_size > 0:
  127. totalPage = totalPage + 1
  128. pagination = {"current_page": current_page, "page_size": page_size, "count": countNum, "total_page": totalPage}
  129. querySql = "select * from (" + sql + ") tmp limit %s,%s"
  130. logging.debug("查询SQL:{}".format(querySql))
  131. # 判断是否有参数
  132. if param == None:
  133. # 无参数
  134. pagination["data"] = self.query(querySql, (offset, page_size))
  135. else:
  136. # 有参数的情况,此时需要判断参数是元祖还是字典
  137. if isinstance(param, dict):
  138. # 字典的情况,因此需要添加字典
  139. querySql = "select * from (" + sql + ") tmp limit %(tmp_offset)s,%(tmp_pageSize)s"
  140. param["tmp_offset"] = offset
  141. param["tmp_pageSize"] = page_size
  142. pagination["data"] = self.query(querySql, param)
  143. elif isinstance(param, tuple):
  144. # 元祖的方式
  145. listtp = list(param)
  146. listtp.append(offset)
  147. listtp.append(page_size)
  148. pagination["data"] = self.query(querySql, tuple(listtp))
  149. else:
  150. # 基础类型
  151. listtp = []
  152. listtp.append(param)
  153. listtp.append(offset)
  154. listtp.append(page_size)
  155. pagination["data"] = self.query(querySql, tuple(listtp))
  156. return pagination
  157. def count(self, sql, param=None):
  158. """
  159. 统计当前表记录行数
  160. :param sql: 统计SQL语句
  161. :param param: 参数
  162. :return: 当前记录行
  163. """
  164. ret = self.queryOne(sql, param)
  165. count = None
  166. if ret:
  167. for k, v in ret.items():
  168. count = v
  169. return count
  170. def insert(self, sql, param=None):
  171. """
  172. 数据库插入
  173. :param sql: SQL语句
  174. :param param: 参数
  175. :return: 受影响的行数
  176. """
  177. return self.execute(sql, param)
  178. def update(self, sql, param=None):
  179. """
  180. 更新操作
  181. :param sql: SQL语句
  182. :param param: 参数
  183. :return: 受影响的行数
  184. """
  185. return self.execute(sql, param)
  186. def delete(self, sql, param=None):
  187. """
  188. 删除操作
  189. :param sql: 删除SQL语句
  190. :param param: 参数
  191. :return: 受影响的行数
  192. """
  193. return self.execute(sql, param)
  194. def batch(self, sql, param=None):
  195. """
  196. 批量插入
  197. :param sql: 插入SQL语句
  198. :param param: 参数
  199. :return: 受影响的行数
  200. """
  201. return self.cursor.executemany(sql, param)
  202. def commit(self, param=None):
  203. """
  204. 提交数据库
  205. :param param:
  206. :return:
  207. """
  208. if param == None:
  209. self.connect.commit()
  210. else:
  211. self.connect.rollback()
  212. def close(self):
  213. """
  214. 关闭数据库连接
  215. :return:
  216. """
  217. if self.cursor:
  218. self.cursor.close()
  219. if self.connect:
  220. self.connect.close()
  221. logging.debug("释放数据库连接")
  222. return None