【问题标题】:How to filter a Model with a One-To-Many Relationship using Flask-Sqlalchemy?如何使用 Flask-Sqlalchemy 过滤具有一对多关系的模型?
【发布时间】:2021-10-22 00:38:27
【问题描述】:

我是 Flask-SQL-Alchemy 的新手,所以这可能是一个菜鸟问题。假设我有一个 Tweet 模型:

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)

现在,我想在 User 表上应用不同的过滤器。例如,获取所有1970出生的名字为John的用户

filters = (
  User.first_name == 'John',
  User.birth_year == 1970
)
users = User.query.filter(*filters).all()

到目前为止,一切都很好!但是现在我想为tweets 属性添加一个过滤器,该过滤器不是real 数据库列,而是ORM 提供的东西。如何获取发布超过 20 条推文的Johns?我试过了:

filters = (
  User.first_name == 'John',
  len(User.tweets) > 20
)

但这会引发异常:object of type 'InstrumentedAttribute' has no len()。 我还尝试在 User 模型中添加一个新的混合属性:

class User(db.Model):
    ...

    @hybrid_property
    def tweet_count(self):
        return len(self.tweets)

filters = (
  User.first_name == 'John',
  User.tweet_count > 20
)

但我仍然遇到同样的错误。这似乎是一项常见任务,但我找不到任何文档或相关示例。我是否以错误的方式解决问题?

【问题讨论】:

    标签: python sqlalchemy orm flask-sqlalchemy one-to-many


    【解决方案1】:

    我认为你错过了这里看到的第二部分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")
                    )
    
    

    【讨论】:

      猜你喜欢
      • 2016-08-23
      • 2021-04-03
      • 2015-10-21
      • 2021-08-14
      • 1970-01-01
      • 2021-12-09
      • 2016-06-15
      • 2021-08-31
      • 1970-01-01
      相关资源
      最近更新 更多