如何使用 Flask-Sqlalchemy 过滤具有一对多关系的模型?
How to filter a Model with a One-To-Many Relationship using Flask-Sqlalchemy?
我是 Flask-SQL-Alchemy 的新手,所以这可能是一个菜鸟问题。假设我有一个推文模型:
class Tweet(db.Model):
__tablename__ = 'tweet'
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.String(500), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
还有一个用户模型,它可以有很多推文:
class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.String(50), nullable=False)
last_name = db.Column(db.String(50), nullable=False)
birth_year = db.Column(db.Integer)
tweets = db.relationship('Tweet', backref='user', lazy=True)
现在,我想对用户应用不同的过滤器 table。例如,获取所有出生于 1970
且名字为 John
的用户
filters = (
User.first_name == 'John',
User.birth_year == 1970
)
users = User.query.filter(*filters).all()
到目前为止,一切顺利!但现在我想为 tweets
属性添加一个过滤器,注意它不是 real 数据库列,而是由 ORM 提供的东西。如何获取发布了超过 20 条推文的 John
人?我试过了:
filters = (
User.first_name == 'John',
len(User.tweets) > 20
)
但这会引发异常:object of type 'InstrumentedAttribute' has no len()
。
我还尝试在用户模型中添加一个新的混合 属性:
class User(db.Model):
...
@hybrid_property
def tweet_count(self):
return len(self.tweets)
filters = (
User.first_name == 'John',
User.tweet_count > 20
)
但我仍然得到同样的错误。这似乎是一项常见任务,但我找不到任何文档或相关示例。我是不是以错误的方式处理问题?
我认为您错过了此处显示的第二部分 SQLAlchemy - Writing a hybrid method for child count
from sqlalchemy.sql import select, func
class User(db.Model):
#...
@tweet_count.expression
def tweet_count(cls):
return (select([func.count(Tweet.id)]).
where(Tweet.user_id == cls.id).
label("tweet_count")
)
我是 Flask-SQL-Alchemy 的新手,所以这可能是一个菜鸟问题。假设我有一个推文模型:
class Tweet(db.Model):
__tablename__ = 'tweet'
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.String(500), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
还有一个用户模型,它可以有很多推文:
class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.String(50), nullable=False)
last_name = db.Column(db.String(50), nullable=False)
birth_year = db.Column(db.Integer)
tweets = db.relationship('Tweet', backref='user', lazy=True)
现在,我想对用户应用不同的过滤器 table。例如,获取所有出生于 1970
且名字为 John
filters = (
User.first_name == 'John',
User.birth_year == 1970
)
users = User.query.filter(*filters).all()
到目前为止,一切顺利!但现在我想为 tweets
属性添加一个过滤器,注意它不是 real 数据库列,而是由 ORM 提供的东西。如何获取发布了超过 20 条推文的 John
人?我试过了:
filters = (
User.first_name == 'John',
len(User.tweets) > 20
)
但这会引发异常:object of type 'InstrumentedAttribute' has no len()
。
我还尝试在用户模型中添加一个新的混合 属性:
class User(db.Model):
...
@hybrid_property
def tweet_count(self):
return len(self.tweets)
filters = (
User.first_name == 'John',
User.tweet_count > 20
)
但我仍然得到同样的错误。这似乎是一项常见任务,但我找不到任何文档或相关示例。我是不是以错误的方式处理问题?
我认为您错过了此处显示的第二部分 SQLAlchemy - Writing a hybrid method for child count
from sqlalchemy.sql import select, func
class User(db.Model):
#...
@tweet_count.expression
def tweet_count(cls):
return (select([func.count(Tweet.id)]).
where(Tweet.user_id == cls.id).
label("tweet_count")
)