在Pyramid中使用SQLAlchemy声明性基类和autoload=True

3 投票
2 回答
2772 浏览
提问于 2025-04-17 04:32

我刚接触Pyramid框架,还不太明白如何在Pyramid中使用autoload=true这个选项。我是用pyramid_routesalchemy通过paster创建的项目。

问题是,我有一个init.py文件,它里面用到了initialize_sql这个函数(这个函数会把Base.metadata.bind设置为engine)。在我的一个模型类中,我想使用autoload=true选项(使用声明式基类),但是我总是遇到以下错误:

sqlalchemy.exc.UnboundExecutionError: No engine is bound to this Table's MetaData. Pass an engine to the Table via autoload_with=<someengine>, or associate the MetaData with an engine via metadata.bind=<someengine>

其实Base.metadata.bind = engine是在initialize_sql函数里面定义的,我不太清楚文件加载的顺序,但我几乎可以肯定init.py是在模型之前加载的,因此metadata已经绑定到engine上了...

所以,我的问题是:我该如何在我的类中使用autoload,而不需要改变整个init和模型的结构呢?

如果有人能给点提示...提前谢谢!

2 个回答

1

从SQLAlchemy 0.8版本开始,你可以在创建声明性基础时使用DeferredReflection类,这样可以延迟自动加载,直到一个引擎连接到你的元数据上。

from sqlalchemy.ext.declarative import declarative_base, DeferredReflection

Base = declarative_base(cls=DeferredReflection)

详细信息请查看这里:http://docs.sqlalchemy.org/en/rel_0_8/orm/extensions/declarative.html#using-reflection-with-declarative

1

这里的基本意思是,自动加载的表格在没有有效的引擎时是不能声明的。所以你需要把初始化代码和模型代码分开,确保在设置好引擎并将其连接到元数据之前,不要导入模型。

下面的链接讲得更清楚,但看起来你已经采取了正确的方法。

在Pylons中使用自动加载的SQLAlchemy声明语法

撰写回答