Декларативный синтаксис SQLAlchemy с автозагрузкой (отражением) в Pylons - PullRequest
9 голосов
/ 24 декабря 2010

Я хотел бы использовать автозагрузку для использования базы данных существований.Я знаю, как это сделать без декларативного синтаксиса (модель / _ 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 = или свяжите метаданные с движком через metadata.bind =

Проблема здесь в том, что я не знаю, где взятьмеханизм из (чтобы использовать его в autoload_with) на этапе импорта модели (он доступен в init_model ()).Я попытался добавить

meta.Base.metadata.bind(engine)

в environment.py, но это не работает.Кто-нибудь нашел какое-нибудь элегантное решение?

Ответы [ 3 ]

11 голосов
/ 29 декабря 2010

ОК, думаю, я понял это.Решение состоит в том, чтобы объявить объекты модели вне 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
1 голос
/ 06 ноября 2014

Я только что попробовал это с помощью модуля orm.

Base = declarative_base(bind=engine)

Base.metadata.reflect(bind=engine)

Доступ к таблицам вручную или через цикл или как угодно:

Base.metadata.sorted_tables

Может быть полезно.

0 голосов
/ 28 декабря 2010

Изучите Использование SQLAlchemy с пилонами о том, как привязать метаданные к движку в функции init_model.

Если оператор meta.Base.metadata.bind(engine) успешно связывает метаданные вашей модели с механизмом, вы сможете выполнить эту инициализацию в своей собственной функции init_model. Полагаю, вы не хотели пропускать привязку метаданных в этой функции?

...