加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – SQLAlchemy中的column_property上的延迟加载

发布时间:2020-12-16 22:45:03 所属栏目:Python 来源:网络整理
导读:说我有以下型号: class Department(Base): __tablename__ = 'departments' id = Column(Integer,primary_key=True)class Employee(Base): __tablename__ = 'employees' id = Column(Integer,primary_key=True) department_id = Column(None,ForeignKey(Depa

说我有以下型号:

class Department(Base):
    __tablename__ = 'departments'
    id = Column(Integer,primary_key=True)

class Employee(Base):
    __tablename__ = 'employees'
    id = Column(Integer,primary_key=True)
    department_id = Column(None,ForeignKey(Department.id),nullable=False)
    department = relationship(Department,backref=backref('employees'))

有时,当我查询部门时,我还想获取他们拥有的员工数量.我可以使用column_property实现这一点,如下所示:

Department.employee_count = column_property(
    select([func.count(Employee.id)])
        .where(Employee.department_id == Department.id)
        .correlate_except(Employee))

Department.query.get(1).employee_count # Works

但是,即使我不需要,也总是通过子查询获取计数.显然我不能要求SQLAlchemy在查询时不加载它:

Department.query.options(noload(Department.employee_count)).all()
# Exception: can't locate strategy for 

我也尝试使用混合属性而不是列属性来实现它:

class Department(Base):
    #...

    @hybrid_property
    def employee_count(self):
        return len(self.employees)

    @employee_count.expression
    def employee_count(cls):
        return (
            select([func.count(Employee.id)])
                .where(Employee.department_id == cls.id)
                .correlate_except(Employee))

没有运气:

Department.query.options(joinedload('employee_count')).all()
# AttributeError: 'Select' object has no attribute 'property'

我知道我可以在查询中查询计数作为一个单独的实体,但我真的更喜欢将它作为模型的属性.这在SQLAlchemy中甚至可能吗?

编辑:为了澄清,我想避免N 1问题并将员工数量加载到与部门相同的查询中,而不是在每个部门的单独查询中.

最佳答案
您尝试的加载策略用于关系. column_property的加载方式与普通列的更改方式相同,请参见Deferred Column Loading.

您可以通过将deferred = True传递给column_property来默认延迟加载employee_count.延迟列时,访问属性时会发出select语句.

sqlalchemy.orm中的defer和undefer允许在构造查询时更改它:

from sqlalchemy.orm import undefer
Department.query.options(undefer('employee_count')).all()

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读