在mod_wsgi Flask应用程序中保留状态 [英] Preserving state in mod_wsgi Flask application

查看:125
本文介绍了在mod_wsgi Flask应用程序中保留状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆