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

时间:2019-05-03 01:54:37

标签: python sqlalchemy flask-sqlalchemy

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

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

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

我尝试了以下命令:

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

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

1 个答案:

答案 0 :(得分:1)

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

IljaEverilä在评论中提供的问题的解决方法,请参见下文。

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

  

AttributeError:既不是'InstrumentedAttribute'对象,也不是   与Activity.activity_type关联的“比较器”对象具有一个   属性“查询”

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

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的这一部分。就是说,它在'query'上查找了名为Activity.activity_type的属性,但找不到它。细分错误消息:

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

db.Model属性来自模型继承的db.Model基,并且仅与db.Model处于同一MRO中的对象可用。由于列对象不是从Activity.query继承的,因此您无法通过它们访问查询属性。 Activity.activity_type.query是合法的, 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. 不是合法的。

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

{{1}}