В общем, нашел более лучшее решение.
Позволяет получить всё дерево начиная с определенного родительского элемента и всё связанные элементы из другой таблицы, как мне и нужно было. Всего за один запрос.
Модели
class Category(Base):
__tablename__ = 'category'
idn = Column(INTEGER(11), primary_key=True)
name = Column(VARCHAR(255))
cparent = Column(INTEGER(11), ForeignKey('category.idn'))
children = relationship('Category',
# cascade deletions
cascade="all",
# many to one + adjacency list - remote_side
# is required to reference the 'remote'
# column in the join condition.
backref=backref("parent", remote_side='category.idn'),
# children will be represented as a dictionary
# on the "name" attribute.
collection_class=attribute_mapped_collection('name'),
lazy="joined",
join_depth=3,
)
product = relationship('Product',
collection_class=list,
backref=backref("category", remote_side='category.idn'),
lazy="joined",
join_depth=3, # так как продукты у меня связаны только с третьим уровнем.
)
def __init__(self, name, parent=None):
self.name = name
self.parent = parent
class Product(Base):
__tablename__ = 'product'
idn = Column(INTEGER(11), primary_key=True)
idcat = Column(INTEGER(11), ForeignKey('category.idn'))
cat = relationship("Category")
data = Column(VARCHAR(255))
Чтобы за раз достать всё это, нужно всего лишь выполнить
root_node = session.query( Category).filter( Category.name == root_node_name).first()