我注意到sqlalchemy在列出所有实例并显示派生类的属性时会生成很多查询。考虑以下对象:
class Parent(Base):
__tablename__ = 'parent'
id = Column(String(length=32), primary_key=True)
type = Column(String(length=8))
__mapper_args__ = {
'polymorphic_identity':'parent',
'polymorphic_on':type
}
class Child(Parent):
sth = Column(String(length=256))
__mapper_args__ = {
'polymorphic_identity':'child'
}
我这样查询:
rows=session.query(Parent).all()
for row in rows:
if row.type=='parent':
print(row.id)
elif row.type=='child':
print(row.id+'/'+row.sth)
我想发生的是对数据库的单个查询,例如SELECT * FROM parent
,但是,每次访问row.sth
时,都会对数据库产生查询。
这是一个小示例程序的日志:
INFO:sqlalchemy.engine.base.Engine:SELECT parent.id AS parent_id, parent.type AS parent_type
FROM parent
INFO:sqlalchemy.engine.base.Engine:{}
INFO:sqlalchemy.engine.base.Engine:SELECT parent.sth AS parent_sth
FROM parent
WHERE parent.id = %(param_1)s AND parent.type IN (%(type_1)s)
INFO:sqlalchemy.engine.base.Engine:{'param_1': 'bar', 'type_1': 'child'}
bar/first child
INFO:sqlalchemy.engine.base.Engine:SELECT parent.sth AS parent_sth
FROM parent
WHERE parent.id = %(param_1)s AND parent.type IN (%(type_1)s)
INFO:sqlalchemy.engine.base.Engine:{'param_1': 'baz', 'type_1': 'child'}
baz/second child
foo
我了解为什么sqlalchemy会以这种方式运行,但是对于我的用例来说效率不高。
如果重要的话,后端就是pymysql。
答案 0 :(得分:0)
询问后立即回答自己的问题很有帮助。这是in the documentation to inheritance。上面写着:
仅查询该基类本地的列 […] orm.with_polymorphic()函数提供了一个特殊的AliasedClass,它表示跨子类的一系列列。
这意味着我可以
rows=session.query(with_polymorphic(Parent, [Child])).all()
在上面的示例中,它只需查询数据库一次即可打印所有具有其子类属性的行。