【发布时间】:2019-05-22 03:20:01
【问题描述】:
为了更好的可测试性和其他原因,最好让 SQLAlchemy 数据库会话配置为非全局的,如以下问题中所述:
how to setup sqlalchemy session in celery tasks with no global variable(也在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 不是 db 架构的“所有者”),从而导致工作人员出错。
以可测试的方式处理meta 的优雅方式是什么,并且仍然能够对底层数据库更改做出反应? (使用蒸馏器,如果相关)。
我正在考虑使用 alembic 版本更改作为重新反映的信号,但不太确定如何使它在 celery 中很好地工作。例如,如果不止一个 worker 会同时感知到变化,那么全局 meta 可能会以非线程安全的方式处理。
如果重要的话,在这种情况下使用 celery 是独立的,没有网络框架模块/应用程序/celery 应用程序中存在的任何内容。这个问题也被简化了,因为只使用了 SQLAlchemy Core,而不是对象映射器。
【问题讨论】:
-
您找到解决方案了吗?我面临着一个非常相似的问题。
-
@EdgarRamírezMondragón 自己回答了这个问题。
标签: sqlalchemy celery