SQLAlchemy — пример сложной выборки many to many

Admin SQLAlchemy

Пример выборки через SQLAlchemy, когда нужно забрать данные связанные по цепочке с другими таблицами, где в последней из них нужно отобрать данные по определенному значению.

Имеем класс CategoryGlobal:

class CategoryGlobal(db.Model, RoleMixin):
    __tablename__ = 'categories_global'
    id = db.Column(db.Integer, primary_key=True, unique=True)
    name = db.Column(db.String(255))

Внутри этого класса есть связь с двумя другими таблицами по методу many to many:

items = db.relationship(
    'Item',
    secondary='categories_item',
    backref=db.backref('categories_global'),
)

Там же указано свойство:

@property
def serialize_for_favorites(self):
    return {
        'id': self.id,
        'name': self.name,
        'items': [x.serialize if x.favorite == False else '' for x in self.items],
    }

Рассмотрим последний участок кода:

'items': [x.serialize if x.favorite == False else '' for x in self.items]

Обычно это выглядит так:

'items': [x.serialize for x in self.items]

И в этом случае будут собраны все items для всех categories_global.

Нам же нужно собрать только избранные записи, в которых у item есть значение в колонке favorite и оно равно True. В противном случае вернуть пустой массив. Поэтому и используется сравнение:

if x.favorite == False else ''

Теперь сформируем сам запрос в python, чтобы забрать данные:

query = db.session.query(CategoryGlobal).all()
categories_global = [x.serialize_for_favorites for x in query]

Если item у categories_global существует, но True у favorite нет:

{'items': [], 'id': 11, 'name': 'корова'},
{'items': [''], 'id': 4, 'name': 'бык'},

Из примера выше видно, что там где был item появилось [одинарные кавычки], если было бы у item True, тогда результат был бы такой:

{'items': [], 'id': 11, 'name': 'корова'},
{'items': [{'cats': [{'hidden': False,
                      'id': 263,
                      'name': 'слон'}],
            'date': '2021-09-11',
            'favorite': True,
            'id': 283,
            'name': 'пошел',
            'note': None,
            'time_passed': [{'cat_inner_id': 263,
                             'item_id': 283,
                             'time_passed': 32426}],
            'timestamp': 1631349025.560444,
            'weekday': 'сб'}], 'id': 4, 'name': 'бык'},

Затем можно удалим все где нет значений:

    new_list = categories_global[:]
    for cat in new_list:
        if not cat['items']:
            categories_global.remove(cat)

Теперь в categories_global только одно значение.

Кстати, на сайте нет рекламы. У сайта нет цели самоокупаться, но если вам пригодилась информация можете задонатить мне на чашечку кофе в макдаке. Лайкнуть страницу или просто поблагодарить. Карма вам зачтется.

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

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