2016-07-20 3 views
3

У меня есть column_property на моей модели, которая является счетчиком отношений на вторичной модели.Изолирующий подзапрос от его родителя

membership_total = column_property(
     select([func.count(MembershipModel.id)]).where(
      MembershipModel.account_id == id).correlate_except(None)) 

Это прекрасно работает, пока я не попытаюсь присоединиться к модели членства.

query = AccountModel.query.join(MembershipModel) 
# ProgrammingError: subquery uses ungrouped column "membership.account_id" from outer query 

я могу решить эту проблему путем добавления:

query = query.group_by(MembershipModel.account_id, AccountModel.id) 
# resolves the issue 

Но я не хочу, чтобы сделать это. Я хочу, чтобы это был его собственный остров, который игнорирует все, что делает запрос, и просто фокусируется на возврате количества членства для идентификатора учетной записи конкретной конкретной строки.

Что я могу сделать с помощью свойства column_property, чтобы сделать его более надежным и менее зависимым от того, что делает родительский запрос?

ответ

2

Провод MembershipModel до correlate_except() вместо None, как описано here в документации. Ваш текущий метод позволяет исключить все из предложения FROM-подзапроса, если он может быть соотнесен с окружающим запросом. Когда вы присоединяетесь к MembershipModel, он становится доступен в прилагаемом запросе.

Вот упрощенный пример. Учитывая 2 модели A и B:

In [2]: class A(Base): 
    ...:  __tablename__ = 'a' 
    ...:  id = Column(Integer, primary_key=True, autoincrement=True) 
    ...:  

In [3]: class B(Base): 
    ...:  __tablename__ = 'b' 
    ...:  id = Column(Integer, primary_key=True, autoincrement=True) 
    ...:  a_id = Column(Integer, ForeignKey('a.id')) 
    ...:  a = relationship('A', backref='bs') 

и 2 column_property определения на A:

In [10]: A.b_count = column_property(
    select([func.count(B.id)]).where(B.a_id == A.id).correlate_except(B)) 

In [11]: A.b_count_wrong = column_property(
    select([func.count(B.id)]).where(B.a_id == A.id).correlate_except(None)) 

Если мы запрашиваем только A, все в порядке:

In [12]: print(session.query(A)) 
SELECT a.id AS a_id, (SELECT count(b.id) AS count_1 
FROM b 
WHERE b.a_id = a.id) AS anon_1, (SELECT count(b.id) AS count_2 
FROM b 
WHERE b.a_id = a.id) AS anon_2 
FROM a 

Но если мы объединим B, второе свойство неправильно сопоставляет B из прилагаемого запроса и полностью опускает ОТ-пункт:

In [13]: print(session.query(A).join(B)) 
SELECT a.id AS a_id, (SELECT count(b.id) AS count_1 
FROM b 
WHERE b.a_id = a.id) AS anon_1, (SELECT count(b.id) AS count_2 
WHERE b.a_id = a.id) AS anon_2 
FROM a JOIN b ON a.id = b.a_id 
+0

Спасибо! Документы также имели прецеденты ...: | –

Смежные вопросы