Запросить все поля при использовании наследования одной таблицы - PullRequest
0 голосов
/ 29 января 2019

Я заметил, что 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 ведет себя таким образом, но он недостаточно эффективен для моего варианта использования.

Backend - это pymysql, если это имеет значение.

1 Ответ

0 голосов
/ 29 января 2019

Отвечая на мой вопрос сейчас, после того, как спросить, очень помог.Это в документации к наследованию .Там написано:

запрашиваются только столбцы, локальные для этого базового класса […], функция orm.with_polymorphic () предоставляет специальный класс AliasedClass, представляющий диапазон значений:столбцы между подклассами.

Это означает, что я могу просто

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

в моем примере выше, и ему потребуется только один раз запросить базу данных, чтобы напечатать все строки с их дочерним классоматрибутов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...