2013-08-19 5 views
0

Как я могу указать SQLAlchemy на загрузку отношений «один ко многим»? Я мог бы присоединиться к ним, но это вызывает дубликаты и (в зависимости от размера результата) много накладных расходов. В идеале я хотел бы изменить session.query таким образом, чтобы было отправлено несколько (двух) запросов, возвращающих родителей и все их дочерние объекты. Как это возможно, либо путем настройки SQLA, либо расширения класса сеанса? Или, может быть, это не обычный способ делать что-то в SQLA ...SQLAlchemy извлекает объекты «один ко многим» подзапросом

ответ

0

Отношение «один ко многим» обычно выполняется путем создания атрибута списка в классе «Родительский» («один») и «родительский» backreference в Child (,, many '') класс (смотрите здесь: here).

Таким образом, вы вообще создать родительский класс:

class Parent(Base): 
    __tablename__ = "parents" 
    dbid = Column(Integer, Sequence("parent_seq"), primary_key=True) 
    children = relationship("Child", order_by = "Children.dbid", backref = "_parent") 

    def __init__(self, children = []) 
    self.children = children #remember to initialize children as list! 

И Детский класс:

class Child(Base): 
    __tablename__ = "children" 
    dbid = Column(Integer, Sequence("child_seq"), primary_key=True) 
    parent_dbid = Column(Integer, ForeignKey("parents.dbid")) 

Если вы хотите добавить ребенка к родителю, просто сделать это так:

p = Parent() 
c = Child() 
p.children.append(c) 

session.add(p) 
session.add(c) 
session.commit() 

Затем, если вы хотите загрузить родителя со всеми его дочерними элементами, вы просто загрузите родителя с session.query(...) и дети загружаются автоматически - вам не нужно делать какие-либо соединения, если вы не хотите, например, загружать только родителей, чьи дети имеют определенные значения атрибутов.

Надеюсь, что это поможет. Пожалуйста, напишите комментарий, если что-то неясно - я попытаюсь изменить свой ответ, чтобы указать.

+0

Спасибо за ваш ответ. Сколько запросов будет отправлено SQLA для извлечения всех детей из нескольких родителей? – orange

+0

Это зависит от структуры вашей базы данных и, возможно, от того, какой механизм БД вы используете. Самый простой способ проверить - включить печать всех запросов, которые делает SQLA. Вы можете сделать это при создании движка: 'engine = create_engine (" path_to_your_database ", echo = True)'. Затем создайте сеанс следующим образом: 'Session = sessionmaker (bind = engine)' и 'session = Session()'. Постскриптум Если вам нравится мой ответ, пожалуйста, примите это;). – Wookie88

+0

SQLA, похоже, по умолчанию запрашивает дочерние элементы для каждого родителя. Поведение можно изменить, добавив параметр «lazy» в поле отношений (см. Http://docs.sqlalchemy.org/en/rel_0_7/orm/loading.html#using-loader-strategies-lazy-loading-eager- загрузка). – orange