объединенный псевдоним sqlalchemy не имеет столбцов из обеих таблиц - PullRequest
0 голосов
/ 29 сентября 2011

Все, что мне нужно - это счет из таблицы А, сгруппированный по столбцу из таблицы В, но, конечно, мне нужен элемент из таблицы В, с которым связан каждый счет.Лучше объяснить с помощью кода:

Таблицы A и B. являются объектами модели.

Я стараюсь следовать этому синтаксису , насколько я могу.

Пытатьсячтобы выполнить этот запрос:

sq = session.query(TableA).join(TableB).\
        group_by(TableB.attrB).subquery()

countA = func.count(sq.c.attrA)
groupB = func.first(sq.c.attrB)   

print session.query(countA, groupB).all()     

Но он дает мне AttributeError (sq не имеет attrB)

Я новичок в SA, и мне трудно учиться.(ссылки на рекомендуемые образовательные ресурсы приветствуются!)

1 Ответ

2 голосов
/ 29 сентября 2011

Когда вы делаете подзапрос из оператора select, столбцы, к которым можно получить к нему доступ, должны находиться в предложении столбцов.Возьмем, к примеру, следующее утверждение:

select x, y from mytable where z=5

Если бы мы хотели создать подзапрос, то GROUP BY 'z', это не будет допустимым SQL:

select * from (select x, y from mytable where z=5) as mysubquery group by mysubquery.z

Потому что 'z'отсутствует в предложении столбцов "mysubquery" (это также недопустимо, поскольку' x 'и' y 'также должны быть в GROUP BY, но это другая проблема).

SQLAlchemy работает точно так жепуть.Когда вы говорите query (..). Subquery () или используете функцию alias () для базовой выбираемой конструкции, это означает, что вы заключаете свой оператор SELECT в круглые скобки, присваивая ему (обычно сгенерированное) имя и давая емуновый .c.коллекция, содержащая только те столбцы, которые содержатся в предложении «столбцы», как настоящий SQL.

Так что здесь вам нужно убедиться, что TableB, по крайней мере, столбец, с которым вы работаете извне, доступен,Вы также можете ограничить предложение столбцов только теми столбцами, которые вам нужны:

sq = session.query(TableA.attrA, TableB.attrB).join(TableB).\
        group_by(TableB.attrB).subquery()

countA = func.count(sq.c.attrA)
groupB = func.first(sq.c.attrB)   

print session.query(countA, groupB).all()    

Обратите внимание, что приведенный выше запрос, вероятно, работает только в MySQL, так как в общем случае в SQL запрещено ссылаться на любые столбцы, которые не являются частьюагрегатная функция или часть GROUP BY, когда используется группировка.В этом случае MySQL имеет более расслабленную (и небрежную) систему.

edit: если вы хотите, чтобы результаты были без нулей:

import collections

letter_count = collections.defaultdict(int)
for count, letter in session.query(func.count(MyClass.id), MyClass.attr).group_by(MyClass.attr):
    letter_count[letter] = count

for letter in ["A", "B", "C", "D", "E", ...]:
    print "Letter %s has %d elements" % letter_count[letter]

note letter_count [someletter] по умолчанию обнуляется, если в противном случаене заселен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...