Commits

angri committed ccbc0e7

moved dropping and recreating indices out from rebuild_all_trees

Comments (0)

Files changed (2)

sqlamp/__init__.py

                                      tree_id, order_by)
             path = inc_path(path, opts.steplen)
 
+    def drop_indices(self, session):
+        """
+        Drop mp-related indices.
+
+        Note that in general you need this only in conjunction
+        with :meth:`rebuild_all_trees`, which this method used
+        to be a part of.
+
+        :param session:
+            sqlalchemy `Session` object to bind DDL queries.
+
+        .. versionadded:: 0.6
+        """
+        for index in self._mp_opts.indices:
+            index.drop(bind=session.bind)
+
+    def create_indices(self, session):
+        """
+        Create mp-related indices.
+
+        Note that needed indices are created by default if you
+        use sqlalchemy's DDL facility (like ``table.create()``)
+        on mp-armed table. This method is useful after call
+        to :meth:`rebuild_all_trees`, or when you're setting up
+        sqlamp on an existing table.
+
+        :param session:
+            sqlalchemy `Session` object to bind DDL queries.
+
+        .. versionadded:: 0.6
+        """
+        for index in self._mp_opts.indices:
+            index.create(bind=session.bind)
+
     def rebuild_all_trees(self, session, order_by=None):
         """
         Perform a complete rebuild of all trees on the basis
         of adjacency relations.
 
-        .. note::
-            Drops indexes before processing and recreates it after. Therefore
-            it may block as such operation may require special locks on table
-            and/or index (in PostgreSQL in particular).
-
         :param session:
-            a session object which will be used for both DDL and DML-queries.
+            a session object which will be used for DML-queries. The session's
+            transaction gets commited when rebuilding is done.
         :param order_by:
-            an "order by clause" for sorting root nodes and a
-            children nodes in each subtree.
+            an "order by clause" for sorting root nodes and children nodes
+            in each subtree. By default ordering by primary key is used.
 
         .. versionchanged::
             0.6
             :meth:`rebuild_all_trees` didn't receive ``session`` parameter
             prior to 0.6.
+
+        .. warning::
+            This method no longer drops/creates indices!
+
+        .. versionchanged::
+            0.6
+            Before 0.6 this method was dropping mp-related indices before
+            starting to modify table content and recreating them afterwards.
+            Now these parts are factored out to :meth:`drop_indices`
+            and :meth:`create_indices` respectively.
         """
         opts = self._mp_opts
         order_by = order_by or opts.pk_field
-        for index in opts.indices:
-            index.drop(bind=session.bind)
         roots = session.execute(sqlalchemy.select(
             [opts.pk_field], opts.parent_id_field == None
         ).order_by(order_by))
             )
             self._do_rebuild_subtree(session, node_id, '', 0,
                                      tree_id + 1, order_by)
-        for index in opts.indices:
-            index.create(bind=session.bind)
+        session.commit()
 
     def query(self, session):
         """

tests/functional-tests.py

         data_after = query.execute().fetchall()
         self.assertEqual(data_before, data_after)
 
+    def test_drop_indices(self):
+        Cls.mp.drop_indices(self.sess)
+        [index] =Cls.mp._mp_opts.indices
+        # creating index again should succeed
+        index.create()
+
+    def test_create_indices(self):
+        [index] =Cls.mp._mp_opts.indices
+        index.drop()
+        Cls.mp.create_indices(self.sess)
+        # dropping index again should succeed
+        index.drop()
+
 
 class QueriesTestCase(_BaseFunctionalTestCase):
     def test_descendants(self):