当前,我正在使用flask框架开发Web应用程序,并计划使用池化方法来管理MYSQL DB连接,以减少为每个用户请求建立新连接的开销。但是,在阅读了一些互联网文章之后,我仍然难以实现它,提供的示例对于小型应用程序来说太简单直接了。因此,我想到了几个问题:
- 该池是根据用户请求创建的,还是仅在服务器开始运行后创建一次?
- 我阅读文章说Python mysql.connector的最大池大小为25个连接,这意味着它只能同时支持25个连接吗?如果有> 25个用户同时向数据库发出请求,会不会有问题?
- 重用机制如何工作?如果根据请求建立了新连接,则
MySQLConnectionPool.get_connection()
将从池中返回一个新对象。这意味着如果池为空,它将创建新的连接对象,否则返回现有对象?在请求关闭后,它是否会再次返回到池中以供下次使用? - 尝试实现它之后,出现以下错误,然后设置
pool_reset_session=False
。它能做什么?是否不重置身份验证变量(密码,数据库名称...等)?由于我的应用程序只能使用1个数据库,因此我认为可以禁用它。mysql.connector.errors.NotSupportedError:MySQL版本5.7.2和 更早的版本不支持COM_RESET_CONNECTION。
下面的代码是我尝试过的,只是一个示例代码:
在我的server.py
中一次创建池:
from mysql_connection import *
@api.before_app_first_request
def before_first_request():
#create the pool once only per server startup
createMYSQLConnectionPool()
@api.before_request
def before_request():
#get connection object per request and set to g object to use globally per context
g.conn = getSQLConnection()
@api.after_request
def after_request(response):
#properly close connection before make response
closeSQLConnection()
在mysql_connection.py中:
from mysql.connector import pooling
from flask import g
import mysql.connector
def createMYSQLConnectionPool():
try:
g.mySQLPool = mysql.connector.pooling.MySQLConnectionPool(pool_name="db_pool",pool_reset_session=False,pool_size=25,host='localhost',port='3308',database='sample_db',user='username',password='password')
print("-I- Created MYSQL database pool...",file=sys.stdout)
print ("Printing connection pool properties: ")
print("Connection Pool Name - ",g.mySQLPool.pool_name)
print("Connection Pool Size - ",g.mySQLPool.pool_size)
except Error as e:
print(err,file=sys.stdout)
def getSQLConnection():
try:
#get connection from pool
mySQLconnection = g.mySQLPool.get_connection()
if mySQLconnection.is_connected():
print("-I- Connected to MySQL Database...",file=sys.stdout)
return mySQLconnection
except Error as e:
print(err,file=sys.stdout)
def closeSQLConnection():
if(g.conn.is_connected()):
g.conn.close()
print("-I- MySQL connection is closed...",file=sys.stdout);
在此实现中,我不确定我做得是否正确。流程应为:
- 启动服务器时,它将在用户首次发出请求时创建新池。
- 为此上下文从池对象(分配给g对象)获取连接,并将其返回到g对象的连接。
- 在做出响应之前关闭连接对象(我想返回池)。
- 下一个用户请求将仅从步骤2开始。
但是,当第二个请求来自用户时,此错误是我得到的:
AttributeError:'_AppCtxGlobals'对象没有属性'mySQLPool'
显然,当第二个请求进入时,g.mySQLPool.get_connection()
g对象没有池对象。当我将createMYSQLConnectionPool()
移到@api.before_request
时,问题消失了,但看起来像是在创建每个新请求池。有什么建议吗?