gpt4 book ai didi

python - Flask/Apache 中的 PyMySQL 有时返回空结果

转载 作者:太空狗 更新时间:2023-10-29 21:58:17 25 4
gpt4 key购买 nike

我有一个 Flask 应用程序,在 Apache 中运行,它依赖于 PyMySQL。该应用程序提供了一系列 REST 命令。它在 Python 3 下运行。

在不提供完整源代码的情况下,该程序的结构如下:

#!flask/bin/python
import json
import pymysql
from flask import *

# Used to hopefully share the connection if the process isn't restarted
mysql_connection = None

# Gets the mysql_connection, or opens it
GetStoreCnx():
global mysql_connection
if (mysql_connection != None):
store_connection_string = ""
# Get the connection string from the config file
with open('config/storedb.json', 'r') as f:
store_connection_string = json.load(f)
mysql_connection = pymysql.connect(**store_connection_string)
return mysql_connection;


class Server(Flask):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

# Return results via REST
@app.route('/results1', methods=['GET'])
def get_result1():
cnx = GetStoreCnx();
cursor = cnx.cursor();
query = """
SELECT
result_name,
successful
FROM
results
"""
cursor.execute(query)
cnx.commit()
result = cursor.fetchall()
return json.dumps(result)

# Run server, if needed
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)

还有一些 REST 调用 - 但它们本质上都做同样的事情(即 - 获取连接、创建游标、运行基本的选择查询 - 有时确实有 2 个以上的字段、执行查询、获取结果并将其作为 JSON 对象返回)。那里的提交应该是不必要的,但这似乎是 PyMySQL 的一个运行问题,导致获取旧数据。

问题是这些 REST 调用有时会返回空的 JSON 集(即。[]),进一步的调查表明执行调用有时会返回一个完全空的结果但不会抛出异常。这种情况经常发生——但并非总是如此。有些调用会成功返回值。当我尝试继续调用直到它返回结果时(如:

while(cursor.execute(query) < 1):
pass

) 该进程进入无限循环,最终(快速)阻止 apache 为任何更多请求提供服务。

服务器(目前)每秒仅服务大约 5 个调用。如果我使用开发服务器,则不会出现此问题。

有什么办法可以避免这个错误吗?这是 PyMySQL 的错误吗?我正在做的事情是否阻止了与 MySQL 的正确连接?

最佳答案

您正在创建一个供您的应用程序使用的全局 mysql 连接,但是 pymysql 声明了一个 threadsafety 1,根据 dbapi2 specification意思是:

1   Threads may share the module, but not connections. 

由于 flask 中的并发请求将由不同的线程提供服务,因此您不应共享连接。使用开发服务器时没有遇到任何问题的原因是它运行单线程。

要避免这种情况,您可以:

  • 为每个线程创建一个新连接,将其存储为线程本地以供进一步使用
  • 为每个请求创建一个新连接,将其存储在flask.g中以供进一步使用

为此,您的 GetStoreCnx 函数可以这样更改:

import threading
thread_local = threading.local()

def GetStoreCnx():
if not hasattr(thread_local, 'mysql_connection'):
store_connection_string = ""
# Get the connection string from the config file
with open('config/storedb.json', 'r') as f:
store_connection_string = json.load(f)
mysql_connection = pymysql.connect(**store_connection_string)
thread_local.mysql_connection = mysql_connection
return thread_local.mysql_connection;

SQLAlchemy 对其 scoped_session() 做了类似的事情.这也适用于 flask.g 而不是 thread_local 每个请求一个连接。

关于python - Flask/Apache 中的 PyMySQL 有时返回空结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34169074/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com