Подсчет связанных элементов в модели sqlalchemy с использованием ChoiceType - PullRequest
0 голосов
/ 18 апреля 2019

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

new, 3
использовано, 7
сломано, 5

Вот что я получил прямо сейчас:

class Offer(Base):
    CATEGORIES = [
        (u'new', u'New'),
        (u'used', u'Used'),
        (u'broken', u'Broken')
    ]

    __tablename__ = 'offers'
    id = sa.Column(sa.Integer, primary_key=True)
    summary = sa.Column(sa.Unicode(255))
    category = sa.Column(ChoiceType(CATEGORIES))

Следуя предыдущему ответу, я попробовал что-то вроде этого:

count_categories = db.session.query(
        CATEGORIES.value, func.count(Offer.id)).outerjoin(
        Offer).group_by(CATEGORIES.key).all()

Это, очевидно, не работает, потому что CATEGORIES.value не определен;Как я могу передать CATEGORIES на этот запрос, чтобы получить желаемый результат?«Настройка» кажется довольно распространенной и взята прямо со страницы SQLAlchemy-Utils Типы данных

Ваша помощь очень ценится (уже растут белые волосы)!


Ужасный, но работающий, временный обходной путь:

result = []
for category in Offer.CATEGORIES:
    count = db.session.query(func.count(Offer.id)).filter_by(category=category[0]).all()
    result.append((category[0], category[1], count[0][0]))

1 Ответ

0 голосов
/ 23 апреля 2019

Для подсчета количества предложений для каждой категории необходимо выполнить внешнее соединение между категориями и предложениями. Учитывая, что вы не храните категории в виде таблицы базы данных, вам придется делать это в коде приложения, что не идеально. Вам просто нужно создать новую таблицу категорий и заменить поле категории в пользовательской таблице внешним ключом, присоединяющимся к новой таблице категорий. Следующий код демонстрирует это.

class Offer(Base):
    __tablename__ = 'offers'
    id = sa.Column(sa.Integer, primary_key=True)
    summary = sa.Column(sa.Unicode(255))
    category_id = sa.Column(sa.Integer, sa.ForeignKey("categories.id"))
    category = sa.orm.relationship("Category", back_populates="offers")

class Category(Base):    
    __tablename__ = 'categories'
    id = sa.Column(sa.Integer, primary_key=True)
    name = sa.Column(sa.Unicode(6), unique=True)
    offers = sa.orm.relationship("Offer", back_populates="category")

# populate categories with the same values as your original enumeration
session.add(Category(name="New"))
session.add(Category(name="Used"))
session.add(Category(name="Broken"))

count_categories = session.query(Category.name, func.count(Offer.id)). \
    select_from(Category).outerjoin(Offer).group_by(Category.name).all()
...