SQLAlchemy 声明式语法与 Pylons 中的自动加载(反射) [英] SQLAlchemy declarative syntax with autoload (reflection) in Pylons

查看:31
本文介绍了SQLAlchemy 声明式语法与 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:没有引擎绑定到这个表的元数据.通过 autoload_with=<someengine> 将引擎传递给 Table,或者通过 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 之外声明模型对象.我得出的结论是 __init__.py 在从模块(在本例中为 model)导入某些内容时作为第一个文件导入,这会导致问题,因为模型对象在 <代码>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

这篇关于SQLAlchemy 声明式语法与 Pylons 中的自动加载(反射)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆