筛选查询结果中的嵌套架构行-SQLAlchemy棉花糖

问题描述

请考虑以下内容:一组Accounts可以是StatusACTIVE的{​​{1}}。每个DELETED的一组Entries的状态也为Account

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

ACTIVE/DELETED

为简化以上操作:

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"
  },"status_name": "active"
    }
  }]
}]

查询accounts: 1: active entries: 1: active,2: deleted 2: deleted entries: 1: active 状态过滤的帐户及其条目-返回不包含任何active帐户或条目的对象。

deleted

要过滤当前使用的帐户,

accounts:
  1: active
  entries:
    1: active

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

以下是{@ {1}}中的帐户,条目,状态的模式

# 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,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)

解决方法

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

解决了这个问题

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

就您而言,我认为您的查询应该是:

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