Pylons中具有自动加载(反射)功能的SQLAlchemy声明性语法 [英] SQLAlchemy declarative syntax with autoload (reflection) in Pylons
问题描述
我想使用自动加载功能来使用现有数据库.我知道如何不使用声明性语法(model/_ init _.py):
I would like to use autoload to use an existings database. I know how to do it without declarative syntax (model/_init_.py):
def init_model(engine):
"""Call me before using any of the tables or classes in the model"""
t_events = Table('events', Base.metadata, schema='events', autoload=True, autoload_with=engine)
orm.mapper(Event, t_events)
Session.configure(bind=engine)
class Event(object):
pass
这很好用,但我想使用声明性语法:
This works fine, but I would like to use declarative syntax:
class Event(Base):
__tablename__ = 'events'
__table_args__ = {'schema': 'events', 'autoload': True}
不幸的是,我这样得到:
Unfortunately, this way I get:
sqlalchemy.exc.UnboundExecutionError:没有引擎绑定到此表的MetaData.通过autoload_with =< someengine>将引擎传递到表,或通过metadata.bind =< someengine>
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>
这里的问题是,在导入模型的阶段(在init_model()中可用),我不知道从哪里获得引擎(在autoload_with中使用引擎).我尝试添加
The problem here is that I don't know where to get the engine from (to use it in autoload_with) at the stage of importing the model (it's available in init_model()). I tried adding
meta.Base.metadata.bind(engine)
到environment.py,但是它不起作用.任何人都找到了一些优雅的解决方案?
to environment.py but it doesn't work. Anyone has found some elegant solution?
推荐答案
好的,我想我已经知道了.解决方案是在model/__init__.py
之外声明模型对象.我得出的结论是,从模块(在本例中为model
)导入某些内容时,__init__.py
作为第一个文件被导入,这会引起问题,因为在调用init_model()
之前声明了模型对象.
OK, I think I figured it out. The solution is to declare the model objects outside the model/__init__.py
. I concluded that __init__.py
gets imported as the first file when importing something from a module (in this case model
) and this causes problems because the model objects are declared before init_model()
is called.
为避免这种情况,我在model
模块中创建了一个新文件,例如objects.py
.然后,我在此文件中声明了我所有的模型对象(如Event
).
To avoid this I created a new file in the model
module, e.g. objects.py
. I then declared all my model objects (like Event
) in this file.
然后,我可以像这样导入我的模型:
Then, I can import my models like this:
from PRJ.model.objects import Event
此外,为避免为每个表指定autoload-with
,我在init_model()
的末尾添加了这一行:
Furthermore, to avoid specifying autoload-with
for each table, I added this line at the end of init_model()
:
Base.metadata.bind = engine
这样,我可以不使用样板代码来声明我的模型对象,如下所示:
This way I can declare my model objects with no boilerplate code, like this:
class Event(Base):
__tablename__ = 'events'
__table_args__ = {'schema': 'events', 'autoload': True}
event_identifiers = relationship(EventIdentifier)
def __repr__(self):
return "<Event(%s)>" % self.id
这篇关于Pylons中具有自动加载(反射)功能的SQLAlchemy声明性语法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!