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'}]

Если надо сериализовать один объект то это делается так:

query = db.session.query(Log).filter_by(status='error').order_by(db.desc(Log.created_on))
logs = [query.first().serialize]

Через декоратор @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 — как получить данные в виде списка словарей"