【问题标题】:How to test SQLAlchemy with reflected database如何使用反射数据库测试 SQLAlchemy
【发布时间】:2021-07-24 10:23:34
【问题描述】:

由于我的烧瓶应用程序不应该在我的数据库中写入任何内容,因此我设置了 Flask-SQLAlchemy 以反映我的数据库。这样,当我更改架构时,我不必更改模型:

# app/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

def create_app():
    app = Flask(__name__)
    db.init_app(app)
    with app.app_context():
        db.Model.metadata.reflect(db.engine)
# app/models.py
from app import db

class Data(db.Model):
    __table__ = db.Model.metadata.tables['data']

这一切都很好而且花花公子。但是现在,我想使用 unittest 来实现测试。但我找不到任何应该如何工作的东西?我习惯于制作一个新的 sqlite 数据库进行测试,但我没有任何模型可以在那里编写。这里的标准程序是什么?你把所有东西都复制到sqlite吗?如果有,怎么做?

【问题讨论】:

    标签: sqlalchemy flask-sqlalchemy python-unittest flask-testing


    【解决方案1】:

    这种情况没有一般规则:您的数据库与您的应用程序分离,因此您需要以某种方式获取数据库架构的副本以在本地重新创建。

    许多数据库引擎提供了一种将数据库架构转储到文件的方法,该文件又可用于将架构加载到另一台服务器(或加载到具有不同名称的同一服务器)。

    如果您想坚持使用 Python 和 SQLAlchemy 工具,您可以通过生产数据库上的反射来填充数据库元数据,然后使用元数据在本地数据库上创建表。

    类似这样:在生产服务器上:

    import pickle
    
    import sqlalchemy as sa
    
    
    engine = sa.create_engine(PRODUCTION_DATABASE_URI)
    
    metadata = sa.MetaData()
    metadata.reflect(engine)
    
    # Save the metadata so that it can be transferred to another machine.
    
    with open('metadata.pkl', 'wb') as f:
        pickle.dump(metadata, f)
    

    然后在本地

    # Restore the metadata object
    with open('metadata.pkl', 'rb') as f:
        metadata = pickle.load(f)
    
    engine = sa.create_engine(TEST_DATABASE_URI)
    
    # Create the tables
    metadata.create_all(engine)
    

    【讨论】:

    • 谢谢!这似乎可行,我只是遇到了关于使用模型的不同问题。当我需要在创建应用程序之前导入模型时,它不起作用,因为元数据尚未填充。但我会为此提出另一个问题。
    • 您可以在测试模式下将元数据加载与烧瓶应用程序分离。最初使用metadata.create_all(engine) 创建表,然后稍后在烧瓶应用程序中反映它们。但如果它比这更复杂,请打开一个新问题来解决它。
    • 问题可以在here找到。你能举个小例子吗?我没有完全理解你的意思。
    • 在您的测试代码中,在调用create_app 之前执行metadata.create_all(engine)(甚至可能在db = SQLAlchemy() 之前)
    • 谢谢,现在我明白了。由于元数据在我的情况下绑定到 db 对象,所以我做的有点不同,但它现在可以工作了。我会更新我的问题。
    猜你喜欢
    • 2022-01-19
    • 2013-02-24
    • 1970-01-01
    • 2015-06-13
    • 2021-05-09
    • 1970-01-01
    • 2022-06-21
    • 1970-01-01
    • 2015-06-13
    相关资源
    最近更新 更多