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"