Для лучшей тестируемости и по другим причинам хорошо иметь конфигурацию сеансов базы данных SQLAlchemy неглобальной, как очень хорошо описано в следующем вопросе:
как настроить сеанс sqlalchemy в задачах сельдерея безглобальная переменная (также обсуждаемая в https://github.com/celery/celery/issues/3561)
Теперь вопрос заключается в том, как элегантно обрабатывать метаданные?Если мое понимание правильное, метаданные можно получить один раз, например:
engine = create_engine(DB_URL, encoding='utf-8', pool_recycle=3600,
pool_size=10)
# db_session = get_session() # this is old global session
meta = MetaData()
meta.reflect(bind=engine)
Отражение при выполнении каждой задачи не является хорошим фактором из-за производительности, метаданные являются более или менее стабильной и поточно-ориентированной структурой (если мы толькопрочитайте его).
Однако метаданные иногда изменяются (celery не является «владельцем» схемы БД), вызывая ошибки у рабочих.
Что может быть элегантным способом справиться с meta
в тестируемом виде, плюс все-таки сможете реагировать на изменения в БД?(используется alembic, если это уместно).
Я думал об использовании изменения версии alembic в качестве сигнала для повторного отражения, но не совсем уверен, как заставить его работать в сельдерее.Например, если более чем один работник сразу почувствует изменение, глобальный meta
может обрабатываться без поточной защиты.
Если это имеет значение, использование сельдерея в данном случае автономно, нетмодули / приложения веб-фреймворка / все, что присутствует в приложении сельдерея.Эта проблема также упрощается, поскольку используется только ядро SQLAlchemy, а не средство отображения объектов.