Python 在SQLAlchemy ORM中,如何获取session.query().group_by()中使用的主键列? 问题:

Python 在SQLAlchemy ORM中,如何获取session.query().group_by()中使用的主键列? 问题:,python,postgresql,orm,sqlalchemy,Python,Postgresql,Orm,Sqlalchemy,如何获取多态层次结构中模型类及其所有父类的所有主键列的列表,以便在会话中使用它。query()。group_by 细节 在SQLAlchemy ORM中,如果我查询的类是多态层次结构的一部分,并且我想groupby它的主键,那么我还必须groupby多态层次结构中其父级的所有主键 想象一下受sqlalchemy文档部分启发的以下设置: class员工(基本): __tablename_uu='employee' id=列(整数,主键=True) 名称=列(字符串(50)) 类型=列(字符串(50

如何获取多态层次结构中模型类及其所有父类的所有主键列的列表,以便在
会话中使用它。query()。group_by

细节 在SQLAlchemy ORM中,如果我查询的类是多态层次结构的一部分,并且我想
groupby
它的主键,那么我还必须
groupby
多态层次结构中其父级的所有主键

想象一下受sqlalchemy文档部分启发的以下设置:

class员工(基本):
__tablename_uu='employee'
id=列(整数,主键=True)
名称=列(字符串(50))
类型=列(字符串(50))
__映射器参数={
“多态性身份”:“员工”,
“多态”:类型
}
班主任(员工):
__tablename_uuu='engineer'
id=列(整数,外键('employee.id'),主键=True)
工程师名称=列(字符串(30))
__映射器参数={
“多态性身份”:“工程师”,
}
班级工程任务(基本):
__tablename_uuu=‘工程任务’
id=列(整数,主键=True)
名称=列(字符串(50))
指定的工程师id=列(外键(工程师id))
分配的\u工程师=关系(工程师,backref=backref(“分配的\u任务”,lazy=“动态”))
如果我想做这样的查询

session.query(
    Engineer,
).join(
    Engineer.assigned_tasks,
).add_columns(
    func.count(EngineeringTask.id).label('assigned_task_count'),
).group_by(Engineer.id, Employee.id)
在PostgreSQL中可以进行这样的查询,即从
Engineer
Employee
中选择所有列,但不聚合这些列(重点是我的):

当存在
分组依据(…)时,选择列表表达式引用未分组列是无效的,聚合函数中除外,或未分组列在功能上依赖于分组列时是无效的,因为对于未分组的列,可能会返回多个值。如果分组列(或其子集)是包含未分组列的表的主键,则存在函数依赖关系

但它要求我知道/关心/记住我正在选择的映射类的所有主键列以及多态层次结构中的所有父类(
Engineer.id
Employee.id


如何动态获取多态层次结构中
Engineer
的所有主键列和所有父级的列表?

到目前为止,我能想到的最好方法是使用以下函数:

来自sqlalchemy导入检查
def多态主密钥(cls):
映射器=检查(cls)
从(mapper.columns中的列对应于列,如果是column.primary\u键)
如果mapper.inherits不是None:
多态\u主键(mapper.inherits.entity)的产量
像这样使用它:

query=session.query(
工程师,
).加入(
工程师分配的任务,
).添加列(
函数计数(EngineeringTask.id).label('assigned_task_count'),
).分组依据(*多态主密钥(工程师))
其中
inspect(Engineer)
返回
Engineer.\uuu映射器\uuuu
,它包含:

  • ,映射模型列的迭代器/字典/属性访问器
  • ,它是父实体(如果有)的映射器
由于以下几个原因,这并不令人满意:

  • 有一个应该是主键上的迭代器,但我不能使用它,因为它返回最顶层父级的主键,而不是当前映射的实体,所以我必须遍历
    Mapper.columns
    并检查
    primary\u key
    属性

  • 有一个方法和一个属性都返回一个迭代器,其中包含当前映射器和当前实体的所有“下游”子类的映射器。为什么没有一个等价的超类

但是它完成了任务