Как правильно использовать Factory Boy с сеансом SQLAlchemy (Lazy Loaded)?

Я просто столкнулся с проблемой с моим тестовым набором. Я использую установку с тестами носа, SQLAlchemy, Flask и Factory-Boy

У меня есть следующий код:

def _create_fixtures(self):
    self.user = UserFactory()
    pprint(db.query(User).all())
    db.add(self.user)
    pprint(db.query(User).all())

ведьма возвращает следующее:

[<User #1>, <User #2>]
[<User #1>, <User #2>]

Моя UserFactory выглядит так:

class UserFactory(Factory):
    FACTORY_FOR = User
    FACTORY_SESSION = db
    email = Sequence(lambda n: 'user{0}@wohnortfinder.com'.format(n))
    password = "password"
    username = Sequence(lambda n: 'user{0}'.format(n))

(да, я использую обычную фабрику, а не фабрику SQLAlchemy, потому что это тоже не сработало)

Почему мой заводской объект не хранится в БД? Это не вызывает ошибку, это просто не сохраняет. Я имею в виду, даже если текущая транзакция еще не зафиксирована, запрос позже должен запрашивать фактическую транзакцию, не так ли?

Как ни странно, когда я фиксирую сеанс вручную, возникает ошибка.

InvalidRequestError: No transaction is begun.

Хотя я начал транзакцию при создании объекта сеанса.

def init_engine(uri, **kwargs):
    global engine
    engine = create_engine(uri, **kwargs)
    Base.metadata.create_all(engine)
    db.begin()
    return engine


engine = None

db = scoped_session(lambda: create_session(bind=engine))

Есть идеи, почему это не работает?

Спасибо за ваши мысли

2 ответа

Решение

Хорошо, теперь я вижу одну из моих ошибок. Я создаю определенную сессию. Вместо этого я должен использовать обычный сеанс для моего приложения. Проблема здесь - как я могу лениво начать нормальную сессию?

Я буду нить эту проблему в другом вопросе

для рассматриваемой сессии я нашел ответ на этот конкретный вопрос. Дело в том, что с сессией с ограниченным объемом все мое приложение не будет работать, но тесты будут..

этот код работает с сессией области действия для этой проблемы.

def _create_fixtures(self):
    db.begin()
    self.user = UserFactory()
    db.add(self.user)
    db.commit()

Вы можете определить фабрики factory_boy, не устанавливая сеанс SQLAlchemy, а затем установить его между инициализацией приложения Flask и использованием фабрик, назначив _meta свойство фабричного класса:

db_session = set_up_a_db_session_somehow()
MyFactoryClass._meta.sqlalchemy_session = db_session

Кажется, что это нормально работает с сессией с ограниченным объемом.

Другие вопросы по тегам