12

我开始用 Flask-SQLAlchemy 编写测试,我想为它们添加一些固定装置。我的开发数据库和很多表中有很多很好的数据,所以手动编写数据会很烦人。我真的很想将开发数据库中的数据采样到固定装置中,然后使用它们。有什么好方法可以做到这一点?

4

3 回答 3

4

我会用工厂男孩

要创建一个模型工厂,您只需执行以下操作:

import factory
from . import models

class UserFactory(factory.Factory):
    class Meta:
        model = models.User

    first_name = 'John'
    last_name = 'Doe'
    admin = False

然后创建实例:

UserFactory.create()

添加静态数据只需作为 kwarg 创建

UserFactory.create(name='hank')

因此,要播种一堆东西,请将其放入 for 循环中。:)

于 2017-05-16T21:02:40.983 回答
0

如果您需要使用 SQLAlchemy 或其他 ORM/后端处理固定装置,则可以使用固定装置包:Flask-Fixtures 0.3.3

这是一个简单的库,允许您使用 JSON 或 YAML 为您的单元测试添加数据库设备。

于 2015-12-12T05:36:42.707 回答
0

虽然 Kyle 的回答是正确的,但我们仍然需要为模型工厂提供数据库会话,否则我们将永远不会真正提交到数据库。此外,factory boy 有一个专用的类 SQLAlchemyModelFactory 用于与 SQLAlchemy 交互。

https://factoryboy.readthedocs.io/en/stable/orms.html#sqlalchemy

整个设置可能如下所示:

import pytest
import os
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from factory.alchemy import SQLAlchemyModelFactory


engine = create_engine( os.getenv("SQLALCHEMY_DATABASE_URI"))

SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)


# this resets our tables in between each test
def _reset_schema():  
    db = SessionLocal()
    for table in Base.metadata.sorted_tables:
        db.execute(
            'TRUNCATE {name} RESTART IDENTITY CASCADE;'.format(name=table.name)
        )
        db.commit()


@pytest.fixture
def test_db():
    yield engine
    engine.dispose()
    _reset_schema()



@pytest.fixture
def session(test_db):
    connection = test_db.connect()
    transaction = connection.begin()
    db = scoped_session(sessionmaker(bind=engine))
    try:
        yield db
    finally:
        db.close()
    transaction.rollback()
    connection.close()
    db.remove()


class UserFactory(SQLAlchemyModelFactory):
    class Meta:
        model = models.User

    first_name = 'John'
    last_name = 'Doe'
    admin = False


@pytest.fixture(autouse=True)
def provide_session_to_factories(session):
    # usually you'd have one factory for each db table
    for factory in [UserFactory, ...]:
        factory._meta.sqlalchemy_session = session

于 2022-01-22T22:16:04.193 回答