我想在我的应用程序中使用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']
预期结果将是使反射在不同的蓝图中起作用。
答案 0 :(得分:2)
让它正常工作,这里是完整的解决方案: https://github.com/researcher2/stackoverflow_56885380
我已经使用sqllite3进行测试,运行create_db.py脚本来设置数据库。使用debug.sh运行flask,因为最近的版本似乎不再只在__main__内包含app.run()。
说明
据我了解,如果您需要在单个应用程序或多个应用程序中多次使用视图,蓝图只是将多个视图组合在一起的一种方法。您可以根据需要添加其他路由前缀。
db对象不与蓝图相关联,它与提供配置信息的应用程序相关联。进入蓝图视图后,您将可以使用自动可用的相关应用程序上下文访问db对象。 关于db.reflect,您需要在create_app内进行调用并将其传递给应用对象(首选),或者将应用导入到意大利面条模型中。
可以使用绑定访问多个DB,如所示。
因此,您的蓝图将有权访问所有导入的表,并且flask-sqlalchemy根据绑定知道要使用哪个数据库连接。
我通常是明确定义表的爱好者,因此您可以在代码完成中访问ORM对象和字段。您是否有很多表/字段,或者是否正在创建某种东西来查询表元数据,以便在任何模式下实现完全自动化?就像模式查看器或类似的东西。
这可能对其他来此帖子的人有用: https://flask-sqlalchemy.palletsprojects.com/en/2.x/contexts/
答案 1 :(得分:1)
太棒了!非常感谢你。得到它也起作用。您的提示给了我一个寻找另一种方法的提示:
@blueprint.route('/')
def index():
# pushing app_context() to import MyTable
# now I can use db.reflect() also in models.py
with app.app_context():
from .models import MyTable
results = db.session.query(MyTable).all()
print(results)
for row in results:
print (row)
print(row.versions)
print(row.name)
if results:
return render_template('my_table.html', results=results)
else:
return 'Nothing happend'
然后可以在models.py中进行反射。您发布的链接确实很有帮助,不知道为什么我自己没有迷路……
无论如何,我现在比以前有更多的机会!
干杯,队友!