SQLAlchemy — как получить данные в виде списка словарей

Admin SQLAlchemy

Как получить данные в python из моделей SQLAlchemy в виде списка или списка из словарей.

Основные методы запросов в SQLAlchemy.

Формируем список list из колонки

Получить все ID пользователей в List

user_ids = [x.id for x in db.session.query(User.id).distinct()]

Если вместо User.id запрашивать User, то тоже будет работать, но скорость обработки снизится в разы. При замерах всего из двух строк данных, скорость падала в среднем в 15 раз. Вывод: по возможности всегда доставайте сразу только нужные данные.

То же самое, но не в листе и по отдельности, например, для обработки сразу:

for id in db.session.query(User.id).distinct():
   print(id[0])

Возвращаем список словарей (dicts in list)

r._asdict()

Если мы указываем конкретные колонки, которые хотим забрать PriceMinute.time. Это удобно, когда их немного.

data = [r._asdict() for r in db.session.query(PriceMinute.price, PriceMinute.time).filter_by(ticker=ticker).order_by(
db.desc(PriceMinute.time)).limit(10).all()]

row.__dict__ for row in

Когда нужно забрать все колонки метод _asdict() уже не будет работать. Здесь подойдет другой вариант получения сразу всех данных из таблицы в виде списка со вложенными словарями:

data = [row.__dict__ for row in db.session.query(PriceMinute).filter_by(ticker=ticker).order_by(
db.desc(PriceMinute.time)).limit(10).all()]

Через декоратор @property — с обработкой

Еще один способ вернуть данные в списке с объединенными словарями.

Для этого в классе модели нужно сделать дополнительный метод с декоратором @property. Внутри этого метода возвращать данные в виде словарей.

Этот способ также удобен и тем, что можно обрабатывать данные и возвращать в том формате в котором хотелось бы их видеть. Обрабатывая их при возврате, а не после. Сохраняя при этом чистоту кода в методах.

class Portfolio(db.Model):
    __tablename__ = 'portfolio'
    id = db.Column(db.Integer, primary_key=True, nullable=False)
    user_id = db.Column(db.Integer, ForeignKey('users.id'))
    ticker = db.Column(db.String, nullable=False)

    def __repr__(self):
        return "<user_id={}, ticker={}, name={}>".format(self.user_id, self.ticker, self.name)

    @property
    def serialize(self):
        return {
            'user_id': self.user_id,
            'ticker': self.ticker,
            'name': self.name,
        }

Запрос будет таким:

shares = db.session.query(Portfolio).filter_by(user_id=1)
shares = [x.serialize for x in shares.all()]

Вывод:

[{'user_id': 1, 'ticker': 'ADS', 'name': 'Alliance Data Systems'},
{'user_id': 1, 'ticker': 'WB', 'name': 'Weibo Corporation'}]

Через декоратор @property — без обработки

Когда обрабатывать данные не нужно, можно воспользоваться таким методом (добавить к модели по примеру выше):

@property
def as_dict(self):
    return {c.name: getattr(self, c.name) for c in self.__table__.columns}

Запрос данных:

shares = db.session.query(Portfolio).filter_by(user_id=1)
shares = [x.as_dict for x in shares.all()]

На выходе будет список со словарями из всех данных указанной таблицы.

Обработка данных в виде словарей после

О том как обрабатывать данные представленные в стандартном классе модели SQLAlchemy можно узнать из статьи о vars() или __dict__.

Если вам пригодилась информация, вы можете поблагодарить автора сайта символическим пожертвованием:

Добавить комментарий

Напишите свой комментарий, если вам есть что добавить/поправить/спросить по теме текущей статьи:
"SQLAlchemy — как получить данные в виде списка словарей"