SQLAlchemy возвращает кортеж, а не словарь - PullRequest
9 голосов
/ 13 мая 2010

Я обновил SQLAlchemy до 0,6, но он сломал все. Я заметил, что это возвращает кортеж, а не словарь. Вот пример запроса:

query = session.query(User.id, User.username, User.email).filter(and_(User.id == id, User.username == username)).limit(1)
result = session.execute(query).fetchone()

Этот фрагмент кода используется для возврата словаря в 0,5.

У меня вопрос, как я могу вернуть словарь?

Ответы [ 3 ]

36 голосов
/ 17 мая 2010

session.execute никогда не возвращал dict, он возвращает объект RowProxy, который может быть проиндексирован как dict, использующий либо целочисленные ключи для позиционного поиска, строковые ключи для поиска на основе меток, либо объекты Column для ищите значение этого столбца. Проблема здесь в том, что session.execute(query) не делает то, что вы ожидаете. Он преобразует объект Query в оператор Select, выполняет его и возвращает результат напрямую. Набор результатов ничего не знает об особенностях уровня ORM. Что изменилось между 0,5 и 0,6, так это то, что ORM использует другой алгоритм для пометки столбцов в запросах, теперь он добавляет имя таблицы к метке. Поэтому, когда раньше row['id'] работало, теперь row['users_id'] работает. В обоих случаях row[User.__table__.columns['id']] работает.

Для выполнения запросов ORM вы должны использовать методы .all(), .first() и .one(), либо выполнять итерации по ним, либо использовать числовое индексирование. Запрос возвращает именованные объекты кортежа. Если вам нужен дикт, застегните кортеж с ключами:

row = session.query(User.id, User.username, User.email)\
    .filter(and_(User.id == id, User.username == username)).first()
print("id=%s username=%s email=%s" % row) # positional
print(row.id, row.username) # by label
print(dict(zip(row.keys(), row))) # as a dict
9 голосов
/ 13 мая 2010

Вы уверены, что это не ResultProxy , который при печати выдает себя за кортеж? Многие объекты в ORM - это не то, что возвращает их __str__ функция.

7 голосов
/ 13 мая 2010

Это должно работать: dict(zip(['id','username','email'],result)) (или вы можете использовать словарное понимание, если вы используете Python 3.x).
Кроме того, вам не нужно вызывать session.execute для session.query объекта. Вместо этого вы захотите использовать метод .one(). Это также устраняет необходимость зависания .limit(1) в конце вашего запроса.

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