【问题标题】:Filter nested schema rows in query result - Sqlalchemy (Marshmallow)过滤查询结果中的嵌套模式行 - Sqlalchemy (Marshmallow)
【发布时间】:2021-02-06 02:10:07
【问题描述】:

考虑以下情况:一组Accounts,其Status 可以是ACTIVEDELETED。一组Entries,每个Account 也有一个状态ACTIVE/DELETED

以下是 2 个帐户的数据对象示例:

accounts = [{
  "account_id": 1,
  "status": {
    "status_id": 1,
    "status_name": "active"
  },
  "account_entries": [{
    "entry_id": 1,
    "status": {
      "status_id": 1,
      "status_name": "active"
    }
  }, {
    "entry_id": 2,
    "status": {
      "status_id": 2,
      "status_name": "deleted"
    }
  }]
}, {
  "account_id": 2,
  "status": {
    "status_id": 2,
    "status_name": "deleted"
  },
  "account_entries": [{
    "entry_id": 1,
    "status": {
      "status_id": 1,
      "status_name": "active"
    }
  }]
}]

为了简化上面的:

accounts:
  1: active
  entries:
    1: active,
    2: deleted
  2: deleted
  entries:
    1: active

想要查询帐户及其条目,按 active 状态过滤 - 返回不包含任何 deleted 帐户或条目的对象。

accounts:
  1: active
  entries:
    1: active

要过滤当前使用的活动帐户:

# query all active accounts
all_accounts = Account.query.filter(Account.status_id == "1")

是否可以扩展查询以将过滤器也应用于条目?

以下是以下模式:帐户、条目、状态 - 在 models.py

class Account(db.Model):
    __tablename__ = 'account'

    account_id = db.Column(db.Integer, primary_key=True)

    status_id = db.Column(db.Integer, db.ForeignKey('status.id'))
    status = db.relationship('Status', backref='accounts')

    def __repr__(self):
        return '<Account {}>'.format(self.id)
class Entry(db.Model):
    __tablename__ = 'entry'

    id = db.Column(db.Integer, primary_key=True)

    status_id = db.Column(db.Integer, db.ForeignKey('status.id'), nullable=False)
    status = db.relationship('Status', backref='entries')

    account_id = db.Column(db.Integer, db.ForeignKey('account.id'), nullable=False)
    account = db.relationship('Account', foreign_keys=[account_id], backref=db.backref('account_entries'))

    def __repr__(self):
        return '<Entry {}>'.format(self.id)
class Status(db.Model):
    __tablename__ = 'status'

    id = db.Column(db.Integer, primary_key=True)

    name = db.Column(db.String(100), nullable=False)

    def __repr__(self):
        return '<Status {}>'.format(self.id)

这些是views.py 中设置的架构:

class StatusSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = Status


class EntrySchema(ma.SQLAlchemyAutoSchema):
    status = ma.Nested(StatusSchema)
    account = ma.Nested(lambda: AccountSchema(only=("id", "name")))

    class Meta:
        model = Entry


class AccountSchema(ma.SQLAlchemyAutoSchema):
    account_entries = ma.List(ma.Nested(EntrySchema(exclude=("account",))))
    status = ma.Nested(StatusSchema)

    class Meta:
        model = Account

【问题讨论】:

    标签: python flask-sqlalchemy marshmallow


    【解决方案1】:

    我遇到了类似的问题,并按照 V. Chikunov 的回答 here 解决了它

    对我有用的是将contains_eager() 添加到我的查询中;没有它,我将获得嵌套模式中的所有行,就像它忽略了过滤器语句一样。

    在您的情况下,我认为您的查询应该是:

    all_accounts = Account.query.join(Status) \
                          .filter(Status.name == "active") \
                          .options(contains_eager(Status.name)) \
                          .all()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-07
      • 1970-01-01
      • 2023-03-17
      • 2021-05-03
      • 1970-01-01
      • 2021-08-13
      相关资源
      最近更新 更多