我想在我的应用程序中使用 Flask 的应用程序工厂机制。我的问题是,我在某些蓝图中使用的数据库位置不同,因此我使用绑定(bind)来指向它们。表本身正在生产中并且已经在使用中,因此我需要反射(reflect)它们以便在我的应用程序中使用它们。
问题是由于应用程序上下文,我无法使反射函数工作。我总是收到这样的消息:我正在应用程序上下文之外工作。我完全理解这一点,并且看到,该数据库确实在外部,但不知道如何涉及它。
我尝试了通过 current_app 将应用程序传递到我的 models.py 的不同变体,但没有任何效果。
配置.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']
预期结果是让反射在不同的蓝图中工作。
最佳答案
成功了,完整的解决方案在这里: https://github.com/researcher2/stackoverflow_56885380
我使用sqllite3进行测试,运行create_db.py脚本来设置数据库。使用 debug.sh 运行 Flask,从最近的版本开始,您似乎不能再只在 __main__ 中使用 app.run() 了。
说明
据我了解,如果您需要在单个应用程序或跨多个应用程序中多次使用多个 View ,蓝图只是将它们组合在一起的一种方法。您可以根据需要添加不同的路由前缀。
数据库对象不与蓝图关联,它与提供配置信息的应用程序关联。进入蓝图 View 后,您将可以访问数据库对象,并自动提供相关的应用程序上下文。 关于db.reflect,您需要在create_app内部进行调用并向其传递应用程序对象(首选)或将应用程序导入到意大利面条模型中。
可以使用绑定(bind)来访问多个数据库,如您所示。
因此,您的蓝图将可以访问所有导入的表,并且 Flask-sqlalchemy 知道根据绑定(bind)使用哪个数据库连接。
我通常热衷于显式定义表,这样您就可以在代码完成中访问 ORM 对象和字段。您是否有很多表/字段,或者您正在创建一些东西来查询表元数据以在任何模式上实现完全自动化?就像模式查看器或类似的东西。
这对于其他人来看这篇文章可能会有用: https://flask-sqlalchemy.palletsprojects.com/en/2.x/contexts/
关于python - 在 Flask 工厂设置中反射(reflect)不同的数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56885380/