• Можно ли реализовать сдвиг узлов графа в базе данных одним запросом?

    @toddbarry Автор вопроса
    rPman, То, увеличиваться должна координата узла или уменьшаться - зависит от координат родителей этого узла. Или от того, справа в данную позицию сдвигается соседний с данным узел или слева. Это не сложно реализовать при помощи нескольких последовательных запросов к базе, но хочется производить все действия одним запросом
  • Можно ли реализовать сдвиг узлов графа в базе данных одним запросом?

    @toddbarry Автор вопроса
    я вот это понял что у вас связи узлов друг с другом как то зависят от положения или это не так?

    rPman, Прошу прощения, я сперва не совсем верно понял ваш вопрос. Нет, просто каждый узел прикреплен к некоторйо сетке. И если возникнет необходимость подвинуть некоторый узел 1 на ячейку ниже и в этой нижней ячейке уже находится другой узел 2 - то необходимо сделать так, чтобы координаты узлов скорректировались так, чтобы в каждой ячейке сетки находился толкьо один узел. Например подвинуть узел 2 влево. Это я и пытался пояснить примерами на рисунках
  • Можно ли реализовать сдвиг узлов графа в базе данных одним запросом?

    @toddbarry Автор вопроса
    rPman, Я писал об этом в основном тексте вопроса (про сдвиг вниз). Это просто изменение координат узлов, при котором некоторые из них оказываются ниже чем были например на одну клетку на сетке.

    Нет, связи никак не зависят от расположения узлов. Но некоторую информацию об изменении координат узлов (Ну пусть вручную - просто захотелось чтобы узлы 1, 2 и 3 отображались на сетке ниже чем сейчас) все равно нужно где-то хранить.
  • Можно ли реализовать сдвиг узлов графа в базе данных одним запросом?

    @toddbarry Автор вопроса
    rPman, Я понимаю что координаты узлов графа по большому счету ничего не значат. Но задача в том, чтобы при добавлении новых узлов к графу - весь граф не менялся сильно. А так же информация о том что узлы были например сдвинуты должна где-то храниться. Я просто не могу придумать иного решения, кроме как хранить все координаты в базе.

    Хотя это не совсем так. Я уже придумал вариант обхода проблемы при помощи массива, который хранит координаты узлов в памяти пока запущен сервер. Тут и изменение координат не вызывает трудностей и нет проблем с совпадением уникальных индексов. Хотя теперь потребляется больше памяти. Но как есть, мне кажется, третьего не дано. Или вы можете предложить что нибудь еще?
  • Можно ли реализовать сдвиг узлов графа в базе данных одним запросом?

    @toddbarry Автор вопроса
    longclaps, по двум причинам
    1) gino хорошо интегрируется с aiohttp и работает на asyncpg движке
    2) В свое время меня убедили в том, что лучше использовать реляционную субд (Не знаю - на самом ли деле лучше)
    Конечно, выбор графовой субд для моих целей более логичен, но я решил послушать того, кто компетентен в этих вопросах лучше меня
  • Как реализовать рекурсивное считыание всех потомков объекта в Gino()?

    @toddbarry Автор вопроса
    Дмитрий Шицков, Пример из документации делает немножко не то - в примере с self referencing лишь говорится о том, что если в классе объявлено несколько внешних ключей, то необходимо использовать ссылки. Рекурсивного считывания детей, детей их детей и т д - то есть всех потомков там нет.

    В итоге решение нашлось в использовании
    cte(recursive=True)


    Код получился следующим:
    class Nodes(db.Model):
        __tablename__ = 'nodes'
    
        id = db.Column(db.Integer, primary_key=True)
    
        def __init__(self, *args, **kwargs):
            super(Nodes, self).__init__(*args, **kwargs)
    
    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)
    
        def __init__(self, *args, **kwargs):
            super(Edges, self).__init__(*args, **kwargs)


    a1=await Edges.create(source=1,target=2)
    a2=await Edges.create(source=1,target=3)
    a3=await Edges.create(source=2,target=5)
    a4=await Edges.create(source=2,target=6)
    a5=await Edges.create(source=3,target=4)
    a6=await Edges.create(source=3,target=5)
    a7=await Edges.create(source=4,target=6)
    
    a8=await Edges.create(source=7,target=8)
    a9=await Edges.create(source=7,target=9)
    a10=await Edges.create(source=8,target=9)
    
    descendants = db.select([Edges.source, Edges.target]).where(Edges.source == 3).cte(recursive=True)
    
    parents = descendants.alias()
    edges = Edges.alias()
    descendants = descendants.union(db.select([edges.source, edges.target]).where(edges.source == parents.c.target))
    query = db.select([descendants.c.target, descendants.c.source]).select_from(descendants)
    result = await query.distinct('target').gino.all()
    print(result)


    Я нигде не использую загрузчики, и не знаю - правильно ли это. Все работает как надо, только меня немножко беспокоит качество реализации и оптимизация
  • Как реализовать рекурсивное считыание всех потомков объекта в Gino()?

    @toddbarry Автор вопроса
    Дмитрий Шицков,
    Видимо, вы недавно с python подружились.


    Просто возвращаюсь к нему время от времени, когда появляется на это время. А появляется оно не так часто. С данным декоратором прежде и правда не встречался

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

    @toddbarry Автор вопроса
    К слову, дополнительная таблица как раз существует - эта таблица ребер между узлами графа, в которой для каждого ребра определяется то, из какого узла он исходит и в какой узел приходит.
    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)
  • Как реализовать рекурсивное считыание всех потомков объекта в Gino()?

    @toddbarry Автор вопроса
    Дмитрий Шицков, Уже смотрел. В приведенном примере мне многое не ясно

    class Parent(db.Model):
        __tablename__ = 'parents'
        id = db.Column(db.Integer, primary_key=True)
    
        def __init__(self, **kw):
            super().__init__(**kw)
            self._children = set()
    
        @property
        def children(self):
            return self._children
    
        @children.setter
        def add_child(self, child):
            self._children.add(child)
            child._parents.add(self)
    
    
    class Child(db.Model):
        __tablename__ = 'children'
        id = db.Column(db.Integer, primary_key=True)
    
        def __init__(self, **kw):
            super().__init__(**kw)
            self._parents = set()
    
        @property
        def parents(self):
            return self._parents
    
    
    class ParentXChild(db.Model):
        __tablename__ = 'parents_x_children'
    
        parent_id = db.Column(db.Integer, db.ForeignKey('parents.id'))
        child_id = db.Column(db.Integer, db.ForeignKey('children.id'))
    
    
    query = Parent.outerjoin(ParentXChild).outerjoin(Child).select()
    parents = await query.gino.load(
        Parent.distinct(Parent.id).load(add_child=Child.distinct(Child.id))).all()


    Например где определяется функция set()
    Мне не ясно что происодит когда пишется wrapper '@children.setter'

    Так же в примере используется таблица родителей и таблица детей, в случае использования Self Referencing методы, относящиеся к children и parent будут реализованы в пределах одного класса Nodes?

    На сколько я понимаю, при использовании Self Referencing, в ParentXChild будет использоваться ссылка ForeignKey('nodes.id') как для child_id, так и для parent_id

    Мне приведенная реализация отношения многие ко многим кажется очень запутанной
  • Как реализовать рекурсивное считыание всех потомков объекта в Gino()?

    @toddbarry Автор вопроса
    Дмитрий Шицков, Вот именно, древовидную. Если я не ошибаюсь, в дереве каждый дочерный элемент может иметь одного и только одного родителя. То есть здесь реализуется отношение многие к одному, так же, как указано в примере в документации. Однако мне нужен граф, в котором было бы реализовано отношение многие ко многим, то есть каждый родитель мог бы иметь одного или нескольких детей и каждый дочерний может иметь одного или нескольких родителей. Прошу прощения если я ошибаюсь в понимании понятия дерева и подобное возможно с использованием Self Referencing

    Вот пример
    a   b    c
     \ / \   |
      d   e  f
      |\ /
      g h     
      |
      i
  • Как реализовать рекурсивное считыание всех потомков объекта в Gino()?

    @toddbarry Автор вопроса
    На сколько я понимаю, так просто, используя пример с Self Referencing не получится реализовать отношение многие ко многим в пределах одной таблицы? Но данные, к сожалению, устроены так, что каждый родитель может иметь одного или нескольких детей и у каждого из детей может быть один или несколько родителей - прямо как в примере реализации решения данной задачи для sqlalchemy
  • Как определить цвет пикселя за пределами холста canvas?

    @toddbarry Автор вопроса
    Понятно, жаль, что так :/
    Спасибо за разъяснение
  • Существуют ли библиотеки, позволяющие реализовать совместное редактирование статей на сервисе?

    @toddbarry Автор вопроса
    DevMan, Подошел текстовый редактор quill, основанный на rich-text и delta. Основной причиной выбора стала поддержка kaTeX. И удобный api.
    Спасибо за помощь ещё раз. Я не наего наткнулся в описании rich-text клиентской библиотеки на js.
  • Существуют ли библиотеки, позволяющие реализовать совместное редактирование статей на сервисе?

    @toddbarry Автор вопроса
    DevMan, richtextpy показалась очень подходящей на первый взгляд - завтра буду изучать подробнее. Спасибо вам большое!
  • Существуют ли библиотеки, позволяющие реализовать совместное редактирование статей на сервисе?

    @toddbarry Автор вопроса
    Мне минималистичное решение представляется следующим: В браузере клиента есть библиотека на js, которая ловит Operation Transformation инструкции с сервера и реализует их в блоке textarea (или другом - не важно) а на бекенде просто слушается вебсокет соединение, по которому эти Operation Transformation инструкции просто рассылаются всем редактирующим документ пользователям. То есть в момент когда пользователь вносит изменения - они оборачиваются в инструкции, шлются на сервер, а оттуда всем подключенным клиентам. И затем в браузере этих клиентов интерпретируются при помощи той самой js библиотеки. И всё.

    Основная проблема для меня состоит в самостоятельно написании библиотеки, которая бы оборачивала изменения в javascript инструкции - ее разработка тудоемкий и временизатратный процесс. пересылка же инструкций по websocket - не является проблемой
  • Существуют ли библиотеки, позволяющие реализовать совместное редактирование статей на сервисе?

    @toddbarry Автор вопроса
    Мне минималистичное решение представляется следующим: В браузере клиента есть библиотека на js, которая ловит Operation Transformation инструкции с сервера и реализует их в блоке textarea (или другом - не важно) а на бекенде просто слушается вебсокет соединение, по которому эти Operation Transformation инструкции просто рассылаются всем редактирующим документ пользователям. То есть в момент когда пользователь вносит изменения - они оборачиваются в инструкции, шлются на сервер, а оттуда всем подключенным клиентам. И затем в браузере этих клиентов интерпретируются при помощи той самой js библиотеки. И всё.

    Основная проблема для меня состоит в самостоятельно написании библиотеки, которая бы оборачивала изменения в javascript инструкции - ее разработка тудоемкий и временизатратный процесс. пересылка же инструкций по websocket - не является проблемой
  • Существуют ли библиотеки, позволяющие реализовать совместное редактирование статей на сервисе?

    @toddbarry Автор вопроса
    Александр Аксентьев, Потому что я не могу встроить гугл доки в свой сервис :)
    в этом вся причина

    А про комбайны - комментатор чуть ниже скинул несколько минималистичных решений, среди них есть даже такое, которое не требует настройки бекенда - firepad называется (однако мне оно не подходит, т.к. обменивается данными со сторонним сервисом для синхронизации данных)

    решения найти трудно - я и сам пытался, однако уверен, что они есть и их много, нужно только знать где искать. Я не знаю, поэтому и обратился сюда
  • Существуют ли библиотеки, позволяющие реализовать совместное редактирование статей на сервисе?

    @toddbarry Автор вопроса
    по поводу конклав нигде не нашел документации по использованию - как встроить в приложение и т п
    firepad понравился . и документация на месте, но на сколько я понял использует сторонний сервер для обмена данными. Мне это не очень подходит. А etherpad требует nodejs, в то время как основной проект написан на python с использованием aiohttp

    Может быть есть готовые решения под бекенд на python, не использующие сторонние сервисы для обмена данными?
  • Существуют ли библиотеки, позволяющие реализовать совместное редактирование статей на сервисе?

    @toddbarry Автор вопроса
    Меня чуть-чуть не устраивает, что вики-движок - это своего рода cms (если я не ошибаюсь, не работал с ним никогда) Это немного чересчур для моих задач - мне лишь нужно встроить этот функционал в сервис, реализуемый не на готовых cms. Поэтому хочется найти библиотеку, реализующую такое