在mod_wsgi Flask应用程序中保留状态 [英] Preserving state in mod_wsgi Flask application
问题描述
我有一个在mod_wsgi下运行的Flask应用程序,它可以连接到数据库。有多个进程运行这个应用程序(每个进程只有一个线程)和一个数据库连接的每个进程。
目前我有这样的东西:
$ b
myapp_wsgi.py
import myapp
app = myapp.setup()
def application(environ,start_response):
return app(environ,start_response)
myapp.py
import Flask
$ b $ app = Flask(__ name__)
db = None
def setup():
全局数据库
db = get_db()
#其他设置
返回应用程序
@ app.route(/)
def index():
data = db.get_data()
返回数据
现在在这里使用全局变量感觉很好。如果应用程序是一个类,我可以使用 self.db
,但事实并非如此。有没有更好的,更Pythonic,更Flask esque的方式来做到这一点?
我想这将取决于数据库(和ORM)。如果您使用SQLAlchemy或 flask-sqlalchemy
,(我强烈建议你这样做),你通常会为数据库连接定义一个全局变量。这通常是在 init_app()
函数中设置的。如果您查看应用程序设置代码,您会发现主要的应用程序对象是一个全局变量 app
。很多时候,你会发现数据库对象是一个全局变量 db
,它通常与 app
一起导入到其他你应该看看 >应用程序和请求 -context文档,尤其是上下文的位置,这解释了这是如何工作的。基本上,上下文永远不会在请求(也就是线程)之间共享,所以应该没有竞争条件,也没有问题。
另外, global在你的情况下
关键字是没有必要的。关键是你永远不会改变变量 db
的内容。这是一个控制数据库连接的对象,只能调用它提供的方法。当你想 mutate 变量的内容时,全局
关键字是必要的,通过赋值给它一个新的值。
$ b
所以,我会重构 setup()
如下(最好把它放在 __ init __。py
$ b def setup()(code $> :
app = Flask(__ name__)
db = get_db()#这是一个局部变量现在
#其他任何需要完成的操作
返回应用程序,db
app,db = setup()
然后在mod_wsgi.py
from myapp导入应用程序
def应用程序(environ,start_response):
返回应用程序(environ, start_response)
I have a Flask application running under mod_wsgi that makes a connection to a database. There are multiple processes running this application (only one thread per process) and one database connection for each of these processes.
Currently I have something like this:
myapp_wsgi.py
import myapp
app = myapp.setup()
def application(environ, start_response):
return app(environ, start_response)
myapp.py
from flask import Flask
app = Flask(__name__)
db = None
def setup():
global db
db = get_db()
# Other setup
return app
@app.route("/")
def index():
data = db.get_data()
return data
Now the use of global variables here doesn't feel very good. If the app were a class, I could use self.db
, but it's not. Is there a better, more Pythonic, more Flask-esque way to do this?
This I suppose will depend on the database (and ORM) you're using with. If you're using SQLAlchemy or flask-sqlalchemy
, (which I highly suggest you to do), you will usually define a single global variable for the database connection. This is usually set up in an init_app()
-function. If you look at the application set up code, you'll see that quite often the main flask application object is a global variable app
. Very often you'll find the database object as a global variable db
which is often imported together with the app
to other parts of the application.
You should look at the application and request-context documentation and especially the locality of the context, which explains how this works. Basically the context is never shared between requests (and thus threads), so there should be no race conditions and no problems.
Also, the global
keyword in your case is not necessary. The point is that you will never really change the content of the variable db
. It's an object which controls the database connection and you only call the methods it offers. The global
keyword is necessary when you want to mutate the contents of the variable, by assigning a new value to it.
So, I would refactor the setup()
as follows (and preferrably put this an __init__.py
so it's nicely importable)
from flask import Flask
def setup():
app = Flask(__name__)
db = get_db() #This is a local variable now
# whatever else needs to be done
return app, db
app, db = setup()
And then in the mod_wsgi.py
from myapp import app
def application(environ, start_response):
return app(environ, start_response)
这篇关于在mod_wsgi Flask应用程序中保留状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!