#python-3.x #sqlalchemy #factory-boy
Вопрос:
Что я пытаюсь сделать?
Я пытаюсь создать базовый класс factory boy с набором метаданных класса следующим образом:
class DBFactoryBase(factory.alchemy.SQLAlchemyModelFactory):
class Meta:
sqlalchemy_session = common_session
sqlalchemy_session_persistence = 'flush'
Затем я хочу унаследовать это и использовать на своих заводах вместо factory.alchemy.SQLAlchemyModelFactory:
class SomeFactory(DBFactoryBase):
class Meta:
model = AnSQLAlchemyModel
fake_line_1 = "A'tuin"
fake_line_2 = 'The currently untitled'
fake_line_3 = '42'
По сути, я хочу иметь возможность расширять Мета-класс, а не переопределять его, и, обновляя сеанс базовой модели, я хочу, чтобы другие модели унаследовали этот сеанс.
Почему я пытаюсь это сделать?
Я делаю это для удобства, поэтому мне не нужно переопределять их со всеми моими заводскими классами. Я также делаю это для того, чтобы я мог переопределить сеанс во время выполнения pytest, используя приведенное ниже приспособление. Я не хочу, чтобы мои фабрики определялись внутри светильников, потому что я также хочу использовать те же фабрики для создания демонстрационных данных. Таким образом, мне нужно передать им сеанс БД без тестирования, и создание фабрик в качестве приспособлений помешает мне использовать их в обычных сценариях.
@pytest.fixture(scope="function")
def test_db(engine_factory, enable_override):
engine = engine_factory
testing_session_local = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base.metadata.drop_all(bind=engine)
Base.metadata.create_all(bind=engine)
api.dependency_overrides[get_db] = enable_override
session: Session = testing_session_local()
DBFactoryBase.sqlalchemy_session = session # <-- Please see here
yield session
# Rollback the session => no changes to the database
session.rollback()
# Remove it, so that the next test gets a new Session()
Base.metadata.drop_all(bind=engine)
Если бы это была модель на основе Django, я мог бы получить доступ к мета-классу родительского класса в качестве атрибута с помощью DBFactoryBase.Мета и передайте это в мета-класс, как показано ниже. Я не совсем уверен, как это работает, и я не знаю, как это сделать, когда исходный класс не является моделью Django.
class SomeFactory(DBFactoryBase):
class Meta(DBFactoryBase.Meta):
model = AnSQLAlchemyModel
fake_line_1 = "A'tuin"
fake_line_2 = 'The currently untitled'
fake_line_3 = '42'
Комментарии:
1. Здесь много информации, но у меня нет четкого представления о том, каким должен быть вопрос.
2. Спасибо Snakecharmerb, я просто хочу обновить сеанс в одном месте, передав его в базовую модель.
3. И ты не можешь, потому что …?