在Pyramid中使用SQLAlchemy声明性基类和autoload=True
我刚接触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)
1
这里的基本意思是,自动加载的表格在没有有效的引擎时是不能声明的。所以你需要把初始化代码和模型代码分开,确保在设置好引擎并将其连接到元数据之前,不要导入模型。
下面的链接讲得更清楚,但看起来你已经采取了正确的方法。