繁体   English   中英

如何在Flask-SQLAlchemy中按用户获取不同的列条目数?

[英]How to get number of distinct column entries by user in Flask-SQLAlchemy?

我有一个用户活动数据库。 对于特定用户,我想返回他们执行的不同类型的活动的数量。 例如:

鲍勃:
活动1:A型
活动2:B型
活动3:A型

由于两个不同的活动(A和B),结果应为2。

我尝试了以下命令:

Activity.activity_type.query.filter(Activity.user_id==1).distinct(Activity.activity_type) 

Activity.activity_type部分给出了错误。 我查看了StackOverflow和文档,但是找不到在这种情况下如何正确使用distinct 我希望能获得有关如何使此查询正常工作的帮助。

请原谅我对您目标的原始解释,这是不正确的,因为返回的是每次尝试进行的活动的计数,而不是对尝试进行的不同活动的计数。

请参见下面的IljaEverilä在评论中提供的问题解决方案。

但是,您遇到的异常发生在执行查询之前(我认为,因为我已经根据提供的查询对模型进行了反向工程),因此,此答案的大部分重点是:

AttributeError:与Activity.activity_type关联的'InstrumentedAttribute'对象和'Comparator'对象均没有属性'query'

我创建这些模型是为了执行您的查询:

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(16))

class Activity(db.Model):
    activity_id = db.Column(db.Integer, primary_key=True)
    activity_type = db.Column(db.String(32))
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    user = db.relationship('User')

然后写了一个小脚本来添加一些数据:

if __name__ == '__main__':
    with app.app_context():
        db.drop_all()
        db.create_all()
        names = ['batman', 'a', 'list', 'of', 'names']
        users = [User(name=name) for name in names]
        db.session.add_all(users)
        activities = [
            'Self Doubt',
            'Dark Introspection',
            'Gotham Needs Me',
            'Training Montage',
            'Fight Crime',
            'Get the girl'
        ]
        db.session.add_all(
            [Activity(
                activity_type=random.choice(activities),
                user=random.choice(users)
            ) for _ in range(20)]
        )

        db.session.commit()

执行Activity.activity_type.query.filter(Activity.user_id==1).distinct(Activity.activity_type)会产生上述错误。

问题出在查询Activity.activity_type.query这一部分。 就是说,它在Activity.activity_type查找名为'query'的属性,但找不到它。 细分错误消息:

当我们在模型上定义Activity.activity_type我们知道它是Column的实例,但是print(Activity.activity_type)显示<class 'sqlalchemy.orm.attributes.InstrumentedAttribute'> ,因此这是错误中引用的第一个对象。 Comparitor是一个内部SQLAlchemy的构造,也检查(你可以找到它Activity.activity_type.comparator如果你有兴趣)。 因此sqlalchemy在Activity.activity_type列上查找但找不到名称为'query'的属性。

.query属性来自您的模型继承的db.Model库,并且仅可用于与db.Model处于同一MRO中的对象。 因为列对象不继承自db.Model ,所以您无法通过它们访问查询属性。 Activity.query合法, Activity.activity_type.query非法。

这是Ilja在对我的原始答案的评论中提供的查询,这是正确的解决方案:

        batman_activity_count = db.session.query(
            db.func.count(
                Activity.activity_type.distinct()
            )
        ).filter(Activity.user_id==1).scalar()

        print(batman_activity_count)  # random integer b/w 0 and 6.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM