12

我想使用自动加载来使用现有数据库。我知道如何在没有声明性语法的情况下做到这一点(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

这很好用,但我想使用声明性语法:

class Event(Base):
    __tablename__ = 'events'
    __table_args__ = {'schema': 'events', 'autoload': True}

不幸的是,这样我得到:

sqlalchemy.exc.UnboundExecutionError:没有引擎绑定到此表的元数据。通过 autoload_with=<someengine> 将引擎传递给表,或通过 metadata.bind=<someengine> 将 MetaData 与引擎关联

这里的问题是,在导入模型的阶段(它在 init_model() 中可用),我不知道从哪里获取引擎(在 autoload_with 中使用它)。我尝试添加

meta.Base.metadata.bind(engine)

到 environment.py 但它不起作用。有人找到了一些优雅的解决方案吗?

4

4 回答 4

12

好吧,我想我明白了。解决方案是在model/__init__.py. 我得出的结论是,__init__.py当从模块中导入某些东西(在这种情况下model)时,它会作为第一个文件导入,这会导致问题,因为模型对象是在init_model()调用之前声明的。

为了避免这种情况,我在model模块中创建了一个新文件,例如objects.py. Event然后我在这个文件中声明了我的所有模型对象(如)。

然后,我可以像这样导入我的模型:

from PRJ.model.objects import Event

此外,为了避免autoload-with为每个表指定,我在末尾添加了这一行init_model()

Base.metadata.bind = engine

这样我就可以在没有样板代码的情况下声明我的模型对象,如下所示:

class Event(Base):
    __tablename__ = 'events'
    __table_args__ = {'schema': 'events', 'autoload': True}

    event_identifiers = relationship(EventIdentifier)

    def __repr__(self):
        return "<Event(%s)>" % self.id
于 2010-12-29T16:51:55.340 回答
1

我刚刚尝试使用 orm 模块。

Base = declarative_base(bind=engine)

Base.metadata.reflect(bind=engine)

手动或通过循环或其他方式访问表:

Base.metadata.sorted_tables

可能有用。

于 2014-11-06T09:46:18.790 回答
0

查看Using SQLAlchemy with Pylons 教程,了解如何将元数据绑定到init_model函数中的引擎。

如果该meta.Base.metadata.bind(engine)语句成功地将您的模型元数据绑定到引擎,您应该能够在自己的init_model函数中执行此初始化。我猜你的意思不是要跳过这个函数中的元数据绑定,是吗?

于 2010-12-28T04:19:00.483 回答
0
from sqlalchemy import MetaData,create_engine,Table
engine = create_engine('postgresql://postgres:********@localhost/db_name')

metadata = MetaData(bind=engine)

rivers = Table('rivers',metadata,autoload=True,auto_load_with=engine)

from sqlalchemy import select

s = select([rivers]).limit(5)
engine.execute(s).fetchall()

为我工作。由于在创建MetaData()对象时未指定绑定,我收到错误消息。

于 2020-11-02T17:59:47.720 回答