簡體   English   中英

過濾查詢結果中的嵌套模式行 - Sqlalchemy (Marshmallow)

[英]Filter nested schema rows in query result - Sqlalchemy (Marshmallow)

請考慮以下情況: 一組具有ACTIVEDELETED StatusAccounts 每個Account一組Entries也具有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

我有一個類似的問題,並按照 V. Chikunov 的回答在這里解決了它

對我有用的是將contains_eager()添加到我的查詢中; 沒有它,我會得到嵌套模式中的所有行,就像它忽略了過濾器語句一樣。

在您的情況下,我認為您的查詢應該是:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM