我有以下一点代码:
import sqlite3
from flask import Flask
app = Flask(__name__)
db = sqlite3.connect('/etc/db.sqlite')
@app.route('/')
def handle():
# run a query and return a response
if __name__ == '__main__':
app.run('0.0.0.0', 8080, debug=True)
但是,当我尝试在请求处理程序中对数据库对象执行某些操作时,我从sqlite3获得以下异常,因为它不是一个线程安全的库,并且查询是从Flask生成的另一个线程运行的,而不是从主线程:
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread.The object was created in thread id 139886422697792 and this is thread id 139886332843776
我知道这样做的“正确”方法是创建一个函数来创建sqlite3.Connection
对象的实例并将其存储在Flask g
全局中,如下所述:http://flask.pocoo.org/docs/1.0/patterns/sqlite3/。但是,在生产中运行此应用程序时,我使用gunicorn -w 4 -b 0.0.0.0:8080 app:app
,并且它工作正常,因为在这种情况下,线程在开始时生成。
虽然Flask g
全局方法适用于所有情况,但我真的希望避免在每次请求时创建和销毁sqlite3.Connection
对象的开销。所以,我想在Flask中禁用线程,以便上面的代码可以运行而不会引起问题。
但是,即使我将上面代码的最后一行更改为app.run(..., threaded=False)
,我也无法避免此错误。好像Flask仍然会产生一个处理请求的线程。
那么,如何使用Flask禁用线程?
不要直接在烧瓶中使用sqlite3
模块。使用Flask_sqlalchemy
我在没有它的情况下尝试在sqlite上设置数据库时遇到了很多麻烦。一旦我进行了切换,它就变得非常容易了。您也可以连接到多种类型的SQL数据库!
Flask sqlalchemy:
http://flask-sqlalchemy.pocoo.org/2.3/
真的是烧瓶的最佳指南:
https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-iv-database