在Python中使用Mysql数据库连接池
最近大量数据库操作,运行程序一段时间之后,数据库连接会断开,具体问题描述可参考这篇文章:MySQL大量操作断开连接
python编程中可以使用MySQLdb进行数据库的连接及诸如查询/插入/更新等操作,但是每次连接mysql数据库请求时,都是独立的去请求访问,相当浪费资源,而且访问数量达到一定数量时,对mysql的性能会产生较大的影响。因此,实际使用中,通常会使用数据库的连接池技术,来访问数据库达到资源复用的目的。
这样就可以避免导致端口耗尽,与数据库服务器断开连接。
具体实现代码在这片文章中已经很详细了,在此不多说。
下面是一些查询的示例:def query_duplicate_ip(self, ip):
"""
查询重复IP,避免浪费IP-API次数
:param ip:
:return 如果存在记录,返回结果,如果没有记录返回False:
"""
# 申请资源
mysql = Mysql()
sql = "SELECT * FROM ip_query_result WHERE ip = '{query_ip}';".format(query_ip=ip)
try:
query_ip_result = mysql.get_one(sql)
# 查询完成之后释放连接
mysql.dispose()
except (MySQLdb.Error, MySQLdb.Warning) as e:
self._logger_ip_filter.error(
' 执行query_duplicate_ip函数的时候出现错误,具体错误内容: {error_message}'.format(error_message=e))
return False
if query_ip_result:
return query_ip_result
else:
return False
上面是获取单条记录的使用方式。def clean_counters(self):
"""保存访客原始数据,用于后面深度学习"""
start = time.time()
# 间隔1分钟
end = start - (1 * 60)
get_visit_time_line = self._redis_conn.lrange('visit_time_line', 0, -1)
for item in get_visit_time_line:
if float(item) > end:
continue
else:
get_ip = self._redis_conn.hget("time:" + item, "ip")
get_url = self._redis_conn.hget("time:" + item, "url")
get_user_agent = self._redis_conn.hget("time:" + item, "user_agent")
mysql = Mysql()
sql = "INSERT INTO visit_time_line_original(time, ip, url,user_agent) VALUES (%s, %s, %s, %s)"
try:
mysql.insert_one(sql, (item, get_ip, get_url, get_user_agent))
mysql.dispose()
except (MySQLdb.Error, MySQLdb.Warning) as e:
self._logger_save_data.error('保存Redis到数据库的时候出现错误,具体错误内容: {error_message} '.format(error_message=e))
上面是插入单条记录的调用方式,mysql.insert_one(sql, (item, get_ip, get_url, get_user_agent)) 这里是插入具体的值。
连接池对性能的提升表现在:
1.在程序创建连接的时候,可以从一个空闲的连接中获取,不需要重新初始化连接,提升获取连接的速度
2.关闭连接的时候,把连接放回连接池,而不是真正的关闭,所以可以减少频繁地打开和关闭连接
黄兵个人博客原创。