本文介绍了在Flask出厂设置中反映不同的数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的应用程序中使用Flask的应用程序工厂机制.我的想法是,我在某些蓝图中使用的数据库位于不同的位置,因此我使用绑定来指向它们.这些表本身已经在生产中并且已经在使用中,因此我需要对其进行反映,以便在我的应用程序中使用它们.

I'd like to use Flask's application factory mechanism fpr my application. I have is that the databases I use within some blueprints are located differently, so I'm using binds for pointing to them. The tables itself are in production and already in use, so I need to reflect them in order to use them within my application.

问题是由于应用程序上下文,我无法使反射功能正常工作.我总是得到这样的消息:我正在应用程序上下文之外工作.我完全理解这一点,并且看到该数据库确实在外面,但是对如何使用它不再有任何想法.

Problem is that I can't get the reflect function working because of the application context. I always get the message, that I'm working outside the application context. I fully understand that and see, that db is really outside, but don't have any idea anymore on how to involve it.

我尝试了通过current_app将应用程序传递给我的models.py的各种变体,但是没有任何效果.

I tried different variations on passing app via current_app to my models.py, but nothing was working.

config.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:

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:

webapp/main/init.py:

def create_module(app):
    from .controller import blueprint
    app.register(blueprint)

webapp/main/controller.py:

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:

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']

预期结果将是使反射在不同的蓝图中起作用.

Expected result would be to get the reflection working in different blueprints.

推荐答案

使其正常运行,此处提供完整解决方案: https://github.com/researcher2/stackoverflow_56885380

Got it working, full solution here:https://github.com/researcher2/stackoverflow_56885380

我已经使用sqllite3进行测试,运行create_db.py脚本来设置数据库.使用debug.sh运行flask,因为最近的版本似乎不再只在__main__内包含app.run().

I have used sqllite3 for the test, run create_db.py script to setup db. Run flask with debug.sh, since recent versions you can't seem to just app.run() inside __main__ anymore.

说明

据我了解,如果您需要在单个应用程序或多个应用程序中多次使用视图,蓝图只是将多个视图组合在一起的一种方法.您可以根据需要添加其他路由前缀.

As I understand it a blueprint is just a way to group together several views if you need to use them multiple times in a single app or across multiple apps. You can add different route prefix as you desire.

db对象不与蓝图相关联,它与提供配置信息的应用程序相关联.进入蓝图视图后,您将可以使用相关的应用程序上下文自动访问db对象.关于db.reflect,您需要在create_app内进行调用并将其传递给应用对象(首选),或者将应用导入到意大利面条模型中.

A db object is not associated with a blueprint, it is associated with an app, which provide the configuration information. Once inside the blueprint views you will have access to the db object with the relevant app context automatically available.Regarding the db.reflect, you need to make the call inside create_app and pass it the app object(preferred) or import the app inside the model which is spaghetti.

可以使用绑定访问多个DB,如所示.

Multiple DBs can be accessed using binding as you've shown.

因此,您的蓝图将有权访问所有导入的表,并且flask-sqlalchemy根据绑定知道要使用哪个数据库连接.

So your blueprints will have access to all tables imported and flask-sqlalchemy knows which db connection to use based on the binding.

我通常是明确定义表的爱好者,因此您可以在代码完成中访问ORM对象和字段.您是否有很多表/字段,或者是否正在创建某种查询表元数据的方法,以实现任何模式上的完全自动化?就像模式查看器或类似的东西.

I'm normally a fan of explicitly defining tables so you have access to the ORM objects and fields in code completion. Do you have lots of tables/fields or maybe you are creating something to query table metadata for total automation on any schema? Like a schema viewer or something like that.

这可能对其他来此帖子的人有用: https://flask-sqlalchemy.palletsprojects.com/en/2.x /contexts/

This might be useful for others coming to this post:https://flask-sqlalchemy.palletsprojects.com/en/2.x/contexts/

这篇关于在Flask出厂设置中反映不同的数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-23 13:01