【发布时间】:2019-07-04 09:56:58
【问题描述】:
我想在我的应用程序中使用 Flask 的应用程序工厂机制。我有的是我在一些蓝图中使用的数据库位置不同,所以我使用绑定来指向它们。表本身已投入生产并已在使用中,因此我需要反映它们以便在我的应用程序中使用它们。
问题是由于应用程序上下文,我无法使反射函数正常工作。我总是得到消息,我在应用程序上下文之外工作。我完全理解这一点,并且看到,db 确实在外面,但对如何参与它一无所知。
我尝试了通过 current_app 将应用程序传递给我的 models.py 的不同变体,但没有任何效果。
config.py:
class Config(object):
#Secret key
SECRET_KEY = 'my_very_secret_key'
ITEMS_PER_PAGE = 25
SQLALCHEMY_BINDS = {
'mysql_bind': 'mysql+mysqlconnector://localhost:3306/tmpdb'
}
SQLALCHEMY_TRACK_MODIFICATIONS = False
main.py:
from webapp import create_app
app = create_app('config.Config')
if __name__ == '__main__':
app.run(debug=true)
webapp/init.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app(config_object):
app=Flask(__name__)
app.config.from_object(config_object)
db.init_app(app)
from main import create_module as main_create_module
main_create_module(app)
return app
webapp/main/init.py:
def create_module(app):
from .controller import blueprint
app.register(blueprint)
webapp/main/controller.py:
from flask import Blueprint, render_template, current_app as app
from .models import db, MyTable # <-- Problem might be here ...
bluerint = Blueprint('main', __name__)
@blueprint.route('/'):
def index():
resp = db.session.query(MyTable)\
.db.func.count(MyTable.versions)\
.filter(MyTable.versions =! '')\
.group_by(MyTable.name).all()
if resp:
return render_template('index.html', respo=respo)
else:
return 'Nothing happend'
webapp/main/models.py:
from .. import db # <-- and here ...
db.reflect(bind='mysql_bind')
class MyTable(db.Model):
__bind_key__ = 'mysql_bind'
__table__ = db.metadata.tables['my_table']
预期的结果是让反射在不同的蓝图中工作。
【问题讨论】:
-
你能帮我试试这个吗,我想你需要在应用程序中注册数据库。 db = SQLAlchemy(app) 而不是 db = SQLAlchemy()。注意我发现在某些情况下使用 vanilla SQLAlchemy 和烧瓶更容易。上下文和将所有内容连接在一起变得不那么痛苦了。
-
这将是正常行为,但在工厂设置中,您宁愿采用我上面描述的方式。实际上,使用
db.init_app(app)和db = SQLAlchemy(app)是一样的。在我描述的示例中,它不会产生任何影响,因为无论哪种方式,db 对象都不能在models.py中调用,它只能在没有工厂设置的情况下使用 Flask 和 SQLAlchemy(你称之为“vanilla SQLAlchemy”)。 -
嗯,我尝试了很多,但这件事似乎无法解决。唯一的解决方案是在
webapp/__init__.py中跳过create_app并在导入时已经初始化 db。因此,它减少了头痛。好,老,普通的“香草烧瓶”。 :) -
在
db.init_app(app)行后尝试create_app()包括db.reflect(app=app)。 -
我觉得还是可以的,但是如果你没有多个app,就没有必要使用app factory。以后可能会玩这个。
标签: python python-3.x flask flask-sqlalchemy