title: sqlalchemy / ltree update request result different than the expected one
body: <p>I have some problem with sqlalchemy during a <code>session.execute</code> query.</p>
  <pre><code>sqlalchemy version       == 1.3.5
  sqlalchemy utils version == 0.34.1
  postgres version         == 10
  </code></pre>
  <p>I implemented a function to update ltree nodes with sqlalchemy, taking inspiration from this article:
  <a href="https://dzone.com/articles/manipulating-trees-using-sql-and-the-postgres-ltre" rel="nofollow noreferrer">https://dzone.com/articles/manipulating-trees-using-sql-and-the-postgres-ltre</a></p>
  <p>I'm trying to move the branch from 1 parent to 0.</p>
  <pre><code>           root                              parent                root
               |                                  |
          root.parent            TO          parent.child
               |
       root.parent.child
  </code></pre>
  <p>I implemented the function <code>set_ltree_path</code> that should cover all scenarios</p>
  <pre class="lang-py prettyprint-override"><code>from sqlalchemy import exc
  from sqlalchemy_utils import Ltree
  
  from api_messages import MESSAGES
  
  
  def uuid_to_path(obj_uuid):
      return str(obj_uuid).replace(&quot;-&quot;, &quot;_&quot;)
  
  
  def move_to(db_object, old_path, new_path, session):
      db_object.path = new_path
      update_descendants_query = f&quot;&quot;&quot;
      UPDATE {db_object.__tablename__}
          SET path = :new_path || subpath(path, nlevel(:old_path) - 1)
          WHERE path &lt;@ :old_path;
      &quot;&quot;&quot;
      session.execute(
          update_descendants_query, {&quot;new_path&quot;: str(new_path), &quot;old_path&quot;: str(old_path)}
      )
  
  
  def get_new_parent(db_object, parent_uuid, session):
      parent_not_found_error = MESSAGES[&quot;NOT_FOUND_IN_DATABASE&quot;].format(
          &quot;parent_uuid&quot;, str(parent_uuid)
      )
      try:
          new_parent = session.query(db_object.__class__).get(str(parent_uuid))
          if new_parent is None:
              raise Exception(parent_not_found_error)
          return new_parent
      except exc.SQLAlchemyError:
          raise Exception(parent_not_found_error)
  
  
  def set_ltree_path(db_object, parent_uuid, session):
      old_parent_uuid = db_object.parent.uuid if db_object.parent else None
  
      # the element has neither old nor new parent
      if old_parent_uuid is None and parent_uuid is None:
          db_object.path = Ltree(uuid_to_path(db_object.uuid))
          return
  
      # the element parent hasn't change
      if str(old_parent_uuid) == str(parent_uuid):
          return
  
      old_path = (
          Ltree(str(db_object.path))
          if db_object.path
          else Ltree(uuid_to_path(db_object.uuid))
      )
  
      # the element no longer has a parent
      if parent_uuid is None:
          new_path = Ltree(uuid_to_path(db_object.uuid))
          move_to(db_object, old_path, new_path, session)
          return
  
      new_parent = get_new_parent(db_object, parent_uuid, session)
      new_path = Ltree(str(new_parent.path)) + uuid_to_path(db_object.uuid)
  
      move_to(db_object, old_path, new_path, session)
  </code></pre>
  <p>and call it with the <code>db object</code>, <code>None</code> because the parent will be a root node, and the <code>db session</code>.
  At the end, the parent will have the right path, but the child, instead of the expected <code>parent.child</code> path has a <code>parent.parent.child</code> path.
  When I try the update request into postgres everything works fine.
  I'm pretty a new user of sql alchemy, maybe I forget something ?
  Thank you in advance :-)</p>