MySQLConnection.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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 pymysql
  27. from DBUtils.PooledDB import PooledDB
  28. import logging
  29. import configparser
  30. import os
  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