Подтвердить что ты не робот

Возвращение отдельных строк в SQLAlchemy с помощью SQLite

SQLAlchemy Query.distinct ведет себя непоследовательно:

>>> [tag.name for tag in session.query(Tag).all()]
[u'Male', u'Male', u'Ninja', u'Pirate']
>>> session.query(Tag).distinct(Tag.name).count()
4
>>> session.query(Tag.name).distinct().count()
3

Таким образом, вторая форма дает правильный результат, но первая форма - нет. Это похоже на SQLite, но не с Postgres. У меня есть функция, которая передала объект запроса, чтобы применить к ней предложение distinct, поэтому было бы очень сложно переписать все, чтобы использовать второй подход выше. Есть ли что-то очевидное, что мне не хватает?

4b9b3361

Ответ 1

Согласно документам:

При наличии диалекта Postgresql будет отображаться DISTINCT ON ( > ).

Итак, передача выражений столбца в distinct() работает только для PostgreSQL (потому что есть DISTINCT ON).

В выражении session.query(Tag).distinct(Tag.name).count() sqlalchemy игнорирует Tag.name и выдает запрос (отличный от всех полей):

SELECT DISTINCT tag.country_id AS tag_country_id, tag.name AS tag_name 
FROM tag

Как вы сказали, в вашем случае применяется distinct(Tag.name) - поэтому вместо просто count() подумайте об этом:

session.query(Tag).distinct(Tag.name).group_by(Tag.name).count()

Надеюсь, что это поможет.

Ответ 2

Когда вы используете session.query(Tag), вы всегда запрашиваете весь объект Tag, поэтому, если ваша таблица содержит другие столбцы, это не сработает.

Предположим, что существует столбец id, тогда запрос

sess.query(Tag).distinct(Tag.name)

будет производить:

SELECT DISTINCT tag.id AS tag_id, tag.name AS tag_name FROM tag

Аргумент отдельного предложения полностью игнорируется.

Если вам действительно нужны только отдельные имена из таблицы, вы должны явно выбрать только имена:

sess.query(Tag.name).distinct()

дает:

SELECT DISTINCT tag.name AS tag_name FROM tag