使用单表继承时查询所有字段

时间:2019-01-29 19:12:38

标签: sqlalchemy

我注意到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。

1 个答案:

答案 0 :(得分:0)

询问后立即回答自己的问题很有帮助。这是in the documentation to inheritance。上面写着:

  

仅查询该基类本地的列   […]   orm.with_polymorphic()函数提供了一个特殊的AliasedClass,它表示跨子类的一系列列。

这意味着我可以

rows=session.query(with_polymorphic(Parent, [Child])).all()

在上面的示例中,它只需查询数据库一次即可打印所有具有其子类属性的行。