Пожалуйста, извините за мое первоначальное толкование вашей цели, оно было неверным, так как возвращалось количество попыток каждого действия, а не количество попыток отдельных действий.
Ниже приведено решение поставленной проблемы.Илья Эвериля в комментариях.
Однако, исключение, которое вы получаете, происходит до того, как ваш запрос будет выполнен (я думаю, так как я пересмотрел ваши модели из запроса, который вы предоставили), так чтоОсновная часть этого ответа сосредоточена на следующем:
AttributeError: Ни объект «InstrumentedAttribute», ни объект «Comparator», связанный с Activity.activity_type, не имеют атрибута «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
.Он говорит, что он искал атрибут с именем 'query'
на Activity.activity_type
, но не смог его найти.Немного разбив сообщение об ошибке:
Мы знаем, что Activity.activity_type
является экземпляром Column
, когда мы определяем его в модели, но print(Activity.activity_type)
показывает <class 'sqlalchemy.orm.attributes.InstrumentedAttribute'>
, так что это первый объект, на который ссылаютсяв ошибке.Comparitor
- это внутренняя конструкция sqlalchemy, которая также проверяется (вы можете найти ее с помощью Activity.activity_type.comparator
, если вам интересно).Поэтому sqlalchemy искал и не мог найти атрибут с именем 'query'
в столбце Activity.activity_type
.
Свойство .query
происходит из базы db.Model
, от которой наследуются ваши модели ибудет доступен только для объектов в том же MRO , что и db.Model
.Поскольку объекты столбца не наследуются от db.Model
, вы не можете получить доступ к свойству запроса через них.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.