【问题标题】:Flask and SQLAlchemy and the MetaData objectFlask 和 SQLAlchemy 以及 MetaData 对象
【发布时间】:2012-11-18 13:32:35
【问题描述】:

这是我第一次使用这个环境。

我愿意使用的部分 SQLAlchemy 只是允许我使用带有 autoload = True 的 Table 对象查询数据库的部分。我这样做是因为我的表已经存在于数据库(mysql 服务器)中,并且不是通过定义烧瓶模型创建的。

我浏览了所有文档,但似乎没有找到答案。这是一些代码:

app = Flask(__name__)
app.config.from_object(__name__)

metadata = None

def connect_db():
    engine = create_engine(app.config['DATABASE_URI'])
    global metadata
    metadata = MetaData(bind=engine)
    return engine.connect()


@app.before_request
def before_request():
    g.db = connect_db()


@app.teardown_request
def teardown_request(exception):
    g.db.close()

现在您可能想知道为什么我使用名为元数据的全局变量。好的,还有一些代码:

@app.route('/test/<int:id>')
def test(test_result_id):

    testTable = Table('test_table', metadata , autoload=True)

如您所见,我需要该对象是全局的,以便从函数中访问它。

我还在每个需要它的函数中声明了相同的 var testTable。我觉得这不是正确的方法。对于像我这样的案例,我找不到任何最佳实践建议。

谢谢大家!

【问题讨论】:

    标签: python sqlalchemy flask flask-sqlalchemy


    【解决方案1】:

    您在 SQLAlchemy 文档中看到过this snippet 吗?

    也许这会起作用:

    # This is fine as a global global
    metadata = MetaData()
    
    @app.before_first_request
    def autoload_tables():
        meta.reflect(bind=g.db.bind)
    
    @app.route('/')
    def index():
        users_table = meta.tables['users']
    

    这样,您的表格在每个进程中只反映一次,这可能是您想要的。请注意,您的引擎也应该是全局的,因此您无需在 @app.before_request 中创建新引擎 - 应用程序创建是一个更合适的地方。

    如果您的情况非常特殊,每个请求可能需要一个引擎,在这种情况下,您应该考虑 ThreadLocalMetaData 类。

    【讨论】:

    • 您的意思是meta = MetaData()?另外,我不确定 SA 文档的链接是否有效..
    • 嗨 jd,如果对于某些路由我们不需要数据库连接,那么为每个“before_request”反映整个数据库表是多余的,对吧?我们怎样才能避免这种情况?
    • 与数据库的连接应该只进行一次,即 connect_db() 应该在应用实例化时或在before_first_request 回调中调用(而不是在before_request 中)。请注意我的回答中的反思是如何仅在第一个请求之前发生的,而不是在每个请求之前发生的。
    猜你喜欢
    • 2022-07-03
    • 1970-01-01
    • 2014-12-25
    • 2020-01-30
    • 2015-03-25
    • 2019-01-02
    • 2022-01-03
    • 1970-01-01
    • 2018-08-22
    相关资源
    最近更新 更多