Разбор python функции vars() из методов для словарей (dict).
Обширная статья по запросам в SQLAlchemy.
Многие классы python показывают содержимое в виде словаря, но при этом не являются словарем, а являются объектом класса, внутри которого может быть представлен формат данных __dict__.
Если попытаться к такому объекту обратиться с методами словаря, то будут выкидываться ошибки.
Однако, раз такие объекты имеют внутри себя атрибуты __dict__, то можно преобразовать их в словарь. А дальше работать как с обычным словарем.
Разберем на примере
Исключение
vars() не нужен, если запрашиваются конкретные колонки, например так:
Пример
Запрос SQLAlchemy:
С помощью запроса type(response) мы узнаем, что response является объектом list:
С помощью print(response) мы увидим следующее содержимое:
Теперь проверим содержимое отдельного элемента <> класса list:
print(type(s))
Нам показывают, что это класс модели ОРМ SQLAlchemy, содержащий данные из таблицы UserSetting:
Мы не можем работать с ним методами словаря. Нам нужно преобразовать его в словарь явно. Для этого воспользуемся функцией vars() в Python:
setting = vars(s)
print(type(setting))
Так мы превратили содержимое части объекта в словарь:
Вместо vars(s) можно использовать s.__dict__, но первый вариант, как говорится, более «питонист».
Напоследок посмотрим, что находится внутри созданного словаря:
setting = vars(s)
print(setting)
Вместо такого безликого формата данных:
Мы увидим:
'id': 2,
'name': 'analyse_sp500',
'percent': None,
'timer': '120',
'timestamp': 1597834582,
'user_id': 1}
Теперь мы можем использовать любые методы словаря и обращаться к данным привычным образом:
setting[‘name’].
Обратить внимание!
Нельзя применить vars() или .__dict__ к классу class ‘list’.
# Следующее приведет к ошибке!
dicts = vars(response)
Если так сделать будет ошибка:
TypeError: vars() argument must have __dict__ attribute
И все будет верно, ведь класс list не содержит атрибуты словаря. Но в самих листах (списках), если их разбить: for x in response, то внутри будут словари и вот они содержат атрибут словаря.
Однако, мы можем сразу получить данные в словаре. Это в том случае, если мы запрос делаем с конкретизацией колонок, которые хотим забрать PriceMinute.price:
db.session.query(PriceMinute.price, PriceMinute.time).filter_by(ticker=ticker).order_by(
db.desc(PriceMinute.time)).limit(10).all()]
В данном случае мы можем сразу применить к response методы словаря.
Если _asdict нет, то иногда работает так: