gpt4 book ai didi

python - 在 SQLAlchemy 中延迟加载 column_property

转载 作者:太空狗 更新时间:2023-10-30 01:12:52 24 4
gpt4 key购买 nike

假设我有以下模型:

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'))

有时,当我查询部门时,我还想获取他们拥有的员 worker 数。我可以使用 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 'sqlalchemy.orm.properties.ColumnProperty'> (('lazy', 'noload'),)

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

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 中的

deferundefer 允许在构造查询时更改它:

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

关于python - 在 SQLAlchemy 中延迟加载 column_property,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39480514/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com