python - 在 Flask 工厂设置中反射(reflect)不同的数据库

标签 python python-3.x flask flask-sqlalchemy

我想在我的应用程序中使用 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/

相关文章:

python - 如何将数组上采样到任意大小?

python - Pygame 生命游戏运行缓慢

python - python "with"语句怎么写?

nginx - Arduino ESP8266 没有收到来自 HTTP 服务器的所有数据

python - Flask 不打印 sys.stdout.write 消息

python - 创建一个由每个正则表达式替换一个字符串组成的列表?

python - 下载图片,要保存到文件夹,检查文件是否存在

python - 如何在Python中连续连接子列表中的一对坐标?

python - 如何将 OCSP 支持添加到 Python 请求库中?

python - 我在我的 flask 应用程序中使用 cx_freeze,但总是得到 ERR_EMPTY_RESPONSE,为什么?