@toddbarry

Как реализовать рекурсивное считыание всех потомков объекта в Gino()?

База устроена так, что у каждого элемента таблицы может быть один или несколько дочерних элементов этйо же самой таблицы. Прошу помочь с реализацией запроса к базе, который бы возвращал детей, детей детей и т д - то есть всех потомков какого либо элемента. Вариант доставать из базы id дочерних элементов данного, а затем снова отправлять запросы к базе чтобы достать дочерние этих дочерних и т п мне не очень нравится из-за ресурсоемкости. asyncpg, с которым работает gino работает быстрее исполнения кода на python, поэтому рациональнее построить рекурсивный запрос к базе данных.
Я знаю, что эта задача легко решается в sqlalchemy. Пример ее решение приведен например здесь, однако мне необходим запрос именно в gino. Gino, на сколько я понял не поддерживает использование метода relationship, вместо этого подобные запросы реализуются как-то при помощи загрузчиков. в официальном руководстве приведен пример использования метода load для поска всех непосредственных дочерних элементов данного элемента вот здесь. Но я не знаю, как это использовать в решении моей задачи рекурсивного поиска всех потомков данного родителя.

На самом деле идеальным вариантом было бы даже не приведенное по ссылке решение, а решение, использующее немного другую структуру данных, если это возможно.

А именно - следующую

class Nodes(db.Model):
    __tablename__ = 'nodes'

    id = db.Column(db.Integer, primary_key=True)
    info = db.Column(db.Text)

class Edges(db.Model):
    __tablename__ = 'edges'

    id = db.Column(db.Integer, primary_key=True)
    source = db.Column(db.Integer, db.ForeignKey('nodes.id'))
    target = db.Column(db.Integer, db.ForeignKey('nodes.id'))

    _edge_idx = db.Index('edge_idx', 'source', 'target', unique=True)


Вместо того чтобы хранить список непосредственных дочерних элементов в табице Nodes, для меня было бы идеальным вариантом описать связи элементов в таблице edges, и при помощи рекурсивного запроса находить все строки в таблице Edges, такие что параметр target в них был бы заданным (он хранит id узла графа, с которым соединен), затем применял бы тот же запрос к параметрам source полученных строк в Edges - то есть искал бы все строки в таблице Edges, у которых параметр target совпадал бы с ранее полученными значениями параметра source и возвращал бы их значения параметров source и т д пока не останется таких строк, которые бы имели параметр target, равный одному из полученных значений параметра source на предыдущей итерации.

То есть мне гораздо больше нравится вариант поиска потомков с использованием дополнительной таблицы, описывающей связи узлов в графе.

Очень прошу помощи, поскольку сам я, похоже прийти к решению не смогу
  • Вопрос задан
  • 649 просмотров
Пригласить эксперта
Ответы на вопрос 1
Для поиска родителей-потомков есть там Self Referencing, правда экспериментальный.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы