使用ChoiceType

时间:2019-04-18 19:12:24

标签: python sqlalchemy sqlalchemy-utils

这是上一个问题here的后续活动。我想计算每个类别中的报价数量,并以一种可以在Jinja中进行迭代的格式输出它们。

新,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 Data types page

非常感谢您的帮助(已经长出了白发)!


一个可怕但可行的临时解决方法:

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 :(得分:0)

要计算每个类别的要约数量,您需要在类别和要约之间进行外部联接。鉴于您没有将类别存储为数据库表,因此必须在不理想的应用程序代码中执行此操作。您只需要创建一个新的类别表,并用连接到新类别表的外键替换用户表中的类别字段。以下代码演示了这一点。

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()