changeset 08d07aa63e73 in trytond:default
details: https://hg.tryton.org/trytond?cmd=changeset&node=08d07aa63e73
description:
        Add backend documentation

        issue9134
        review269041003
diffstat:

 doc/ref/backend.rst                    |  318 +++++++++++++++++++++++++++++++++
 doc/ref/index.rst                      |    1 +
 doc/ref/models.rst                     |    2 +-
 trytond/backend/database.py            |  115 +-----------
 trytond/backend/postgresql/database.py |    5 +-
 trytond/backend/postgresql/table.py    |   20 +-
 trytond/backend/sqlite/database.py     |    5 +-
 trytond/backend/sqlite/table.py        |   22 +-
 trytond/backend/table.py               |  128 +------------
 trytond/ir/action.py                   |    2 -
 10 files changed, 358 insertions(+), 260 deletions(-)

diffs (953 lines):

diff -r 2f01695e906a -r 08d07aa63e73 doc/ref/backend.rst
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/ref/backend.rst       Thu Sep 08 13:05:06 2022 +0200
@@ -0,0 +1,318 @@
+.. _ref-backend:
+.. module:: trytond.backend
+
+=======
+Backend
+=======
+
+The backend manages the database connection and schema manipulation.
+
+.. attribute:: name
+
+   The name of the backend configured.
+
+.. class:: Database(name)
+
+   Manage the connection to the named database.
+
+.. method:: Database.connect()
+
+   Connect to the database and return the instance.
+
+.. method:: Database.get_connection([autocommit[, readonly]])
+
+   Retrieve a connection object as defined by :pep:249#connection.
+   If autocommit is set, the connection is committed after each statement.
+   If readonly is set, the connection is read only.
+
+.. method:: Database.put_connection(connection[, close])
+
+   Release the connection.
+   If close is set, the connection is discarded.
+
+.. method:: Database.close()
+
+   Close all connections.
+
+.. classmethod:: Database.create(connection, database_name)
+
+   Create the named database using the connection.
+
+.. classmethod:: Database.drop(connection, database_name)
+
+   Drop the named database using the connection.
+
+.. method:: Database.list([hostname])
+
+   Return a list of Tryton database names.
+   ``hostname`` filters the databases with the same configured hostname.
+
+.. method:: Database.init()
+
+   Initialize the database schema.
+
+.. method:: Database.test([hostname])
+
+   Return if the database is a Tryton database.
+   If ``hostname`` is set, it checks also if it has the same configured
+   hostname.
+
+.. method:: Database.nextid(connection, table)
+
+   Return the next ID for the ``table`` using the ``connection``.
+
+   .. note:: It may return ``None`` for some database.
+
+.. method:: Database.setnextid(connection, table, value)
+
+   Set the ``value`` as current ID to the ``table`` using the ``connection``.
+
+.. method:: Database.currid(connection, table)
+
+   Return the current ID of the ``table`` using the ``connection``.
+
+.. classmethod:: Database.lock(connection, table)
+
+   Lock the ``table`` using the ``connection``.
+
+.. method:: Database.lock_id(id[, timeout])
+
+   Return the SQL expression to lock the ``id``.
+   Set ``timeout`` to wait for the lock.
+
+.. method:: Database.has_constraint(constraint)
+
+   Return if the database handle the ``constraint``.
+
+.. method:: Database.has_returning()
+
+   Return if the database supports ``RETURNING`` in ``INSERT`` and ``UPDATE``.
+
+.. method:: Database.has_multirow_insert()
+
+   Return if the database supports ``INSERT`` of multi-rows.
+
+.. method:: Database.has_select_for()
+
+   Return if the database supports ``FOR UPDATE`` and ``FOR SHARE`` in
+   ``SELECT``.
+
+.. method:: Database.get_select_for_skip_locked()
+
+   Return For class with skip locked.
+
+.. method:: Database.has_window_functions()
+
+   Return if the database supports window functions.
+
+.. method:: Database.has_unaccent()
+
+   Return if the database suppport unaccentuated function.
+
+.. method:: Database.unaccent(value)
+
+   Return the SQL expression of unaccentuated ``value``.
+
+.. method:: Database.has_similarity()
+
+   Return if the database suppports similarity function.
+
+.. method:: Database.similarity(column, value)
+
+   Return the SQL expression that compare the similarity of ``column`` and
+   ``value``.
+
+.. method:: Database.has_search_full_text()
+
+   Return if the database suppports full text search.
+
+.. method:: Database.format_full_text(\*documents[, language])
+
+   Return the SQL expression that format the ``documents`` into text search
+   vectors for the ``language``.
+
+   The order of ``documents`` define the weight for proximity ranking.
+
+.. method:: Database.format_full_text_query(query[, language])
+
+   Convert the ``query`` expression into full text query.
+
+.. method:: Database.search_full_text(document, query)
+
+   Return the SQL expression for searching ``document`` with the ``query``.
+
+.. method:: Database.rank_full_text(document, query[, normalize])
+
+   Return the SQL expression to rank ``document`` with the ``query``.
+
+.. classmethod:: Database.has_sequence()
+
+   Return if the database supports sequence querying and assignation.
+
+.. method:: Database.sequence_exist(connection, name)
+
+   Return if the named sequence exists using the ``connection``.
+
+.. method:: Database.sequence_create(connection, name[, number_increment[, 
start_value]])
+
+   Create a named sequence incremented by ``number_increment`` or ``1`` and
+   starting at ``start_value`` or ``1`` using the ``connection``.
+
+.. method:: Database.sequence_update(connection, name[, number_increment[, 
start_value]])
+
+   Modify the named sequence with ``number_increment`` and ``start_value``using
+   the ``connection``.
+
+.. method:: Database.sequence_rename(connection, old_name, new_name)
+
+   Rename the sequece from ``old_name`` to ``new_name`` using the
+   ``connection``.
+
+.. method:: Database.sequence_delete(connection, name)
+
+   Delete the named sequence using the ``connection``.
+
+.. method:: Database.sequence_next_number(connection, name)
+
+   Return the next number fo the named sequence using the ``connection``.
+
+.. method:: Database.has_channel(connection, name)
+
+   Return if the database supports ``LISTEN`` and ``NOTIFY`` on channel.
+
+.. method:: Database.sql_type(type_)
+
+   Return the namedtuple('SQLType', 'base type') corresponding to the SQL
+   ``type_``.
+
+.. method:: Database.sql_format(type_, value)
+
+   Return the ``value`` casted for the SQL ``type_``.
+
+.. method:: Database.json_get(column[, key])
+
+   Return the JSON value of the JSON ``key`` from the ``column``.
+
+.. method:: Database.json_key_exists(column, key)
+
+   Return the SQL expression to test if ``key`` exists in the JSON ``column``.
+
+.. method:: Database.json_any_keys_exist(column, keys)
+
+   Return the SQL expression to test if any ``keys`` exist in the JSON
+   ``column``.
+
+.. method:: Database.json_all_keys_exist(column, keys)
+
+   Return the SQL expression to test if all ``keys`` exist in the JSON
+   ``column``.
+
+.. method:: Database.json_contains(column, json)
+
+   Rteurn the SQL expression to test if the JSON ``column`` contains ``json``.
+
+.. class:: TableHandler(model[, history])
+
+   Handle table for the ``model``.
+   If ``history`` is set, the table is the one storing the history.
+
+.. attribute:: TableHandler.namedatalen
+
+   The maximing length of named data for the database.
+
+.. classmethod:: TableHandler.table_exist(table_name)
+
+   Return if the named table exists.
+
+.. classmethod:: TableHandler.table_rename(old_name, new_name)
+
+   Rename the table from ``old_name`` to ``new_name``.
+
+.. method:: TableHandler.column_exist(column_name)
+
+   Return if the named column exists.
+
+.. method:: TableHandler.column_rename(old_name, new_name)
+
+   Rename the column from ``old_name`` to ``new_name``.
+
+.. method:: TableHandler.alter_size(column_name, column_type)
+
+   Modify the size of the named column using the column type.
+
+.. method:: TableHandler.alter_type(column_name, column_type)
+
+   Modify the type of the named column.
+
+.. method:: TableHandler.column_is_type(column_name, type_[, size])
+
+   Return if the column is of type ``type_``.
+   If ``type`` is ``VARCHAR``, ``size`` is also compared except if the value if
+   negative.
+
+.. method:: TableHandler.db_default(column_name, value)
+
+   Set the default ``value`` on the named column.
+
+.. method:: TableHandler.add_column(column_name, abstract_type[, default[, 
comment]])
+
+   Add the named column of abstract type.
+   The ``default`` is a method that return the value to fill the new column.
+   ``comment`` set as comment for the column.
+
+.. method:: TableHandler.add_fk(column_name, reference[, on_delete])
+
+   Add a foreign key constraint on the named column to target the ``reference``
+   table name.
+   ``on_delete`` defines the method to use when foreign record is deleted.
+
+.. method:: TableHandler.drop_fk(column_name[, table])
+
+   Drop the foreign key constrant on the named column.
+   ``table`` can be used to alter another table.
+
+.. method:: TableHandler.index_action(columns[, action[, where[, table]]])
+
+   Add or remove index on listed ``columns``.
+   ``where`` is an optional SQL expression for partial index.
+   ``table`` can be used to alter another table.
+
+.. method:: TableHandler.not_null_action(column_name[, action])
+
+   Add or remove ``NOT NULL`` on the named column.
+
+.. method:: TableHandler.add_constraint(ident, constraint)
+
+   Add the SQL expression ``constraint`` as constraint named ``ident`` on the
+   table.
+
+.. method:: TableHandler.drop_constraint(ident[, table])
+
+   Drop the named ``ident`` constraint.
+   ``table`` can be used to alter another table.
+
+.. method:: TableHandler.drop_column(column_name)
+
+   Drop the named column.
+
+.. classmethod:: TableHandler.drop_table(model, table[, cascade])
+
+   Drop the named ``table`` and clean ``ir.model.data`` from the given
+   ``model``.
+   Set ``cascade`` to drop objects that depend on the table.
+
+.. classmethod:: TableHandler.convert_name(name)
+
+   Convert the data name to be lower than namedatalen.
+
+.. exception:: DatabaseIntegrityError
+
+   Exception raised when the relational integrity of the database is affected.
+
+.. exception:: DatabaseDataError
+
+   Exception raised for errors that are due to problems with the processed 
data.
+
+.. exception:: DatabaseOperationalError
+
+   Exception raised for errors that are related to the database’s operation.
diff -r 2f01695e906a -r 08d07aa63e73 doc/ref/index.rst
--- a/doc/ref/index.rst Thu Sep 01 22:10:10 2022 +0200
+++ b/doc/ref/index.rst Thu Sep 08 13:05:06 2022 +0200
@@ -15,6 +15,7 @@
    pyson
    transaction
    exceptions
+   backend
    tools/index
    pool
    rpc
diff -r 2f01695e906a -r 08d07aa63e73 doc/ref/models.rst
--- a/doc/ref/models.rst        Thu Sep 01 22:10:10 2022 +0200
+++ b/doc/ref/models.rst        Thu Sep 08 13:05:06 2022 +0200
@@ -538,7 +538,7 @@
 
 .. classmethod:: ModelSQL.__table_handler__([module_name[, history]])
 
-   Return a TableHandler for the Model.
+   Return a :class:`~trytond.backend.TableHandler` instance for the Model.
 
 .. classmethod:: ModelSQL.table_query()
 
diff -r 2f01695e906a -r 08d07aa63e73 trytond/backend/database.py
--- a/trytond/backend/database.py       Thu Sep 01 22:10:10 2022 +0200
+++ b/trytond/backend/database.py       Thu Sep 08 13:05:06 2022 +0200
@@ -24,65 +24,29 @@
         self.name = name
 
     def connect(self):
-        '''
-        Connect to the database
-
-        :return: the database
-        '''
         raise NotImplementedError
 
-    def get_connection(self, autocommit, readonly=False):
-        '''Retrieve a connection on the database
-
-        :param autocommit: a boolean to activate autocommit
-        :param readonly: a boolean to specify if the transaction is readonly
-        '''
+    def get_connection(self, autocommit=False, readonly=False):
         raise NotImplementedError
 
     def put_connection(self, connection, close=False):
-        '''Release the connection
-
-        :param close: if close is True the connection is discarded
-        '''
         raise NotImplementedError
 
     def close(self):
-        '''
-        Close all connection
-        '''
         raise NotImplementedError
 
     @classmethod
     def create(cls, connection, database_name):
-        '''
-        Create a database
-
-        :param connection: the connection to the database
-        :param database_name: the new database name
-        '''
         raise NotImplementedError
 
-    def drop(self, connection, database_name):
-        '''
-        Drop a database
-
-        :param connection: the connection to the database
-        :param database_name: the database name
-        '''
+    @classmethod
+    def drop(cls, connection, database_name):
         raise NotImplementedError
 
     def list(self, hostname=None):
-        '''
-        Get the list of database
-
-        :return: a list of database name
-        '''
         raise NotImplementedError
 
     def init(self):
-        '''
-        Initialize a database
-        '''
         raise NotImplementedError
 
     def test(self, hostname=None):
@@ -92,105 +56,52 @@
         raise NotImplementedError
 
     def nextid(self, connection, table):
-        '''
-        Return the next sequenced id for a table.
-
-        :param connection: a connection on the database
-        :param table: the table name
-        :return: an integer
-        '''
+        pass
 
     def setnextid(self, connection, table, value):
-        '''
-        Set the current sequenced id for a table.
-
-        :param connection: a connection on the database
-        :param table: the table name
-        '''
+        pass
 
     def currid(self, connection, table):
-        '''
-        Return the current sequenced id for a table.
-
-        :param connection: a connection on the database
-        :param table: the table name
-        :return: an integer
-        '''
-
-    def update_auto_increment(self, connection, table, value):
-        '''
-        Update auto_increment value of table
-
-        :param connection: a connection on the database
-        :param table: the table name
-        :param value: the auto_increment value
-        '''
         pass
 
     @classmethod
     def lock(cls, connection, table):
-        '''
-        Lock the table
-
-        :param connection: a connection on the database
-        :param table: the table name
-        '''
         raise NotImplementedError
 
     def lock_id(self, id, timeout=None):
-        """Return SQL function to lock resource"""
         raise NotImplementedError
 
     def has_constraint(self, constraint):
-        '''
-        Return True if database handle constraint.
-
-        :return: a boolean
-        '''
         raise NotImplementedError
 
     def has_returning(self):
-        '''
-        Return True if database implements RETURNING clause in INSERT or UPDATE
-        statements.
-
-        :return: a boolean
-        '''
         return False
 
     def has_multirow_insert(self):
-        'Return True if database supports multirow insert'
         return False
 
     def has_select_for(self):
-        "Return if database supports FOR UPDATE/SHARE clause in SELECT."
         return False
 
     def get_select_for_skip_locked(self):
-        "Return For class with skip locked"
         return For
 
     def has_window_functions(self):
-        "Return if database supports window functions."
         return False
 
     def has_unaccent(self):
-        "Return if database supports unaccentuated searches"
         return False
 
     def unaccent(self, value):
-        "Return the expression to use for unaccentuated columns"
         return value
 
     def has_similarity(self):
-        "Return if database supports similarity"
         return False
 
     def similarity(self, column, value):
         raise NotImplementedError
 
     def has_search_full_text(self):
-        "Return if database supports full text search"
         return False
 
     def format_full_text(self, *documents, language=None):
@@ -200,7 +111,6 @@
         raise NotImplementedError
 
     def search_full_text(self, document, query):
-        "Return the clause expression for searching document against query"
         raise NotImplementedError
 
     def rank_full_text(self, document, query, normalize=None):
@@ -209,75 +119,60 @@
 
     @classmethod
     def has_sequence(cls):
-        "Return if database supports sequence querying and assignation"
         return False
 
     def sequence_exist(self, connection, name):
-        "Return if a sequence exists"
         if not self.has_sequence():
             return
         raise NotImplementedError
 
     def sequence_create(
             self, connection, name, number_increment=1, start_value=1):
-        "Creates a sequence"
         if not self.has_sequence():
             return
         raise NotImplementedError
 
     def sequence_update(
             self, connection, name, number_increment=1, start_value=1):
-        "Modifies a sequence"
         if not self.has_sequence():
             return
         raise NotImplementedError
 
     def sequence_rename(self, connection, old_name, new_name):
-        "Renames a sequence"
         if not self.has_sequence():
             return
         raise NotImplementedError
 
     def sequence_delete(self, connection, name):
-        "Removes a sequence"
         if not self.has_sequence():
             return
         raise NotImplementedError
 
     def sequence_next_number(self, connection, name):
-        "Gets the next number of a sequence"
         if not self.has_sequence():
             return
         raise NotImplementedError
 
     def has_channel(self):
-        "Return True if database supports LISTEN/NOTIFY channel"
         return False
 
     def sql_type(self, type_):
-        'Return the SQLType tuple corresponding to the SQL type'
         pass
 
     def sql_format(self, type_, value):
-        'Return value correctly casted into type_'
         pass
 
     def json_get(self, column, key=None):
-        "Return the JSON value of the JSON key"
         raise NotImplementedError
 
     def json_key_exists(self, column, key):
-        "Return expression for key exists in JSON column"
         raise NotImplementedError
 
     def json_any_keys_exist(self, column, keys):
-        "Return expression for any keys exist in JSON column"
         raise NotImplementedError
 
     def json_all_keys_exist(self, column, keys):
-        "Rteurn expression for all keys exist in JSON column"
         raise NotImplementedError
 
     def json_contains(self, column, json):
-        "Return expression for column contains JSON"
         raise NotImplementedError
diff -r 2f01695e906a -r 08d07aa63e73 trytond/backend/postgresql/database.py
--- a/trytond/backend/postgresql/database.py    Thu Sep 01 22:10:10 2022 +0200
+++ b/trytond/backend/postgresql/database.py    Thu Sep 08 13:05:06 2022 +0200
@@ -293,11 +293,12 @@
         connection.commit()
         cls._list_cache.clear()
 
-    def drop(self, connection, database_name):
+    @classmethod
+    def drop(cls, connection, database_name):
         cursor = connection.cursor()
         cursor.execute(SQL("DROP DATABASE {}")
             .format(Identifier(database_name)))
-        self.__class__._list_cache.clear()
+        cls._list_cache.clear()
 
     def get_version(self, connection):
         version = connection.server_version
diff -r 2f01695e906a -r 08d07aa63e73 trytond/backend/postgresql/table.py
--- a/trytond/backend/postgresql/table.py       Thu Sep 01 22:10:10 2022 +0200
+++ b/trytond/backend/postgresql/table.py       Thu Sep 08 13:05:06 2022 +0200
@@ -94,19 +94,19 @@
                     (self.sequence_name,))
                 self._update_definitions(columns=True)
 
-    @staticmethod
-    def table_exist(table_name):
+    @classmethod
+    def table_exist(cls, table_name):
         transaction = Transaction()
         return bool(transaction.database.get_table_schema(
                 transaction.connection, table_name))
 
-    @staticmethod
-    def table_rename(old_name, new_name):
+    @classmethod
+    def table_rename(cls, old_name, new_name):
         transaction = Transaction()
         cursor = transaction.connection.cursor()
         # Rename table
-        if (TableHandler.table_exist(old_name)
-                and not TableHandler.table_exist(new_name)):
+        if (cls.table_exist(old_name)
+                and not cls.table_exist(new_name)):
             cursor.execute(SQL('ALTER TABLE {} RENAME TO {}').format(
                     Identifier(old_name), Identifier(new_name)))
         # Rename sequence
@@ -117,8 +117,8 @@
         # Rename history table
         old_history = old_name + "__history"
         new_history = new_name + "__history"
-        if (TableHandler.table_exist(old_history)
-                and not TableHandler.table_exist(new_history)):
+        if (cls.table_exist(old_history)
+                and not cls.table_exist(new_history)):
             cursor.execute('ALTER TABLE "%s" RENAME TO "%s"'
                 % (old_history, new_history))
 
@@ -520,8 +520,8 @@
                 Identifier(column_name)))
         self._update_definitions(columns=True)
 
-    @staticmethod
-    def drop_table(model, table, cascade=False):
+    @classmethod
+    def drop_table(cls, model, table, cascade=False):
         cursor = Transaction().connection.cursor()
         cursor.execute('DELETE FROM ir_model_data WHERE model = %s', (model,))
 
diff -r 2f01695e906a -r 08d07aa63e73 trytond/backend/sqlite/database.py
--- a/trytond/backend/sqlite/database.py        Thu Sep 01 22:10:10 2022 +0200
+++ b/trytond/backend/sqlite/database.py        Thu Sep 08 13:05:06 2022 +0200
@@ -475,9 +475,10 @@
             cursor = conn.cursor()
             cursor.close()
 
-    def drop(self, connection, database_name):
+    @classmethod
+    def drop(cls, connection, database_name):
         if database_name == ':memory:':
-            self._local.memory_database._conn = None
+            cls._local.memory_database._conn = None
             return
         if os.sep in database_name:
             return
diff -r 2f01695e906a -r 08d07aa63e73 trytond/backend/sqlite/table.py
--- a/trytond/backend/sqlite/table.py   Thu Sep 01 22:10:10 2022 +0200
+++ b/trytond/backend/sqlite/table.py   Thu Sep 08 13:05:06 2022 +0200
@@ -44,8 +44,8 @@
 
         self._update_definitions()
 
-    @staticmethod
-    def table_exist(table_name):
+    @classmethod
+    def table_exist(cls, table_name):
         cursor = Transaction().connection.cursor()
         cursor.execute("SELECT sql FROM sqlite_master "
             "WHERE type = 'table' AND name = ?",
@@ -80,18 +80,18 @@
             cursor.execute('DROP TABLE "_temp_%s"' % table_name)
         return True
 
-    @staticmethod
-    def table_rename(old_name, new_name):
+    @classmethod
+    def table_rename(cls, old_name, new_name):
         cursor = Transaction().connection.cursor()
-        if (TableHandler.table_exist(old_name)
-                and not TableHandler.table_exist(new_name)):
+        if (cls.table_exist(old_name)
+                and not cls.table_exist(new_name)):
             cursor.execute('ALTER TABLE %s RENAME TO %s'
                 % (_escape_identifier(old_name), _escape_identifier(new_name)))
         # Rename history table
         old_history = old_name + "__history"
         new_history = new_name + "__history"
-        if (TableHandler.table_exist(old_history)
-                and not TableHandler.table_exist(new_history)):
+        if (cls.table_exist(old_history)
+                and not cls.table_exist(new_history)):
             cursor.execute('ALTER TABLE %s RENAME TO %s'
                 % (_escape_identifier(old_history),
                     _escape_identifier(new_history)))
@@ -109,7 +109,7 @@
         cursor = transaction.connection.cursor()
         temp_table = '__temp_%s' % self.table_name
         temp_columns = dict(self._columns)
-        TableHandler.table_rename(self.table_name, temp_table)
+        self.table_rename(self.table_name, temp_table)
         self._init(self._model, history=self.history)
         columns, old_columns = [], []
         for name, values in temp_columns.items():
@@ -368,8 +368,8 @@
         else:
             self._recreate_table(drop_columns=[column_name])
 
-    @staticmethod
-    def drop_table(model, table, cascade=False):
+    @classmethod
+    def drop_table(cls, model, table, cascade=False):
         cursor = Transaction().connection.cursor()
         cursor.execute('DELETE from ir_model_data where model = ?',
             (model,))
diff -r 2f01695e906a -r 08d07aa63e73 trytond/backend/table.py
--- a/trytond/backend/table.py  Thu Sep 01 22:10:10 2022 +0200
+++ b/trytond/backend/table.py  Thu Sep 08 13:05:06 2022 +0200
@@ -40,178 +40,62 @@
             self.sequence_name = self.table_name + '_id_seq'
         self.history = history
 
-    @staticmethod
-    def table_exist(table_name):
-        '''
-        Table exist
-
-        :param table_name: the table name
-        :return: a boolean
-        '''
+    @classmethod
+    def table_exist(cls, table_name):
         raise NotImplementedError
 
-    @staticmethod
-    def table_rename(old_name, new_name):
-        '''
-        Rename table
-
-        :param old_name: the old table name
-        :param new_name: the new table name
-        '''
+    @classmethod
+    def table_rename(cls, old_name, new_name):
         raise NotImplementedError
 
     def column_exist(self, column_name):
-        '''
-        Column exist
-
-        :param column_name: the column name
-        :return: a boolean
-        '''
         raise NotImplementedError
 
     def column_rename(self, old_name, new_name):
-        '''
-        Rename column if exists
-
-        :param old_name: the name of the existing column
-        :param new_name: the new name of the column
-        '''
         raise NotImplementedError
 
     def alter_size(self, column_name, column_type):
-        '''
-        Modify size of a column
-
-        :param column_name: the column name
-        :param column_type: the column definition
-        '''
         raise NotImplementedError
 
     def alter_type(self, column_name, column_type):
-        '''
-        Modify type of a column
-
-        :param column_name: the column name
-        :param column_type: the column definition
-        '''
         raise NotImplementedError
 
     def column_is_type(self, column_name, type_, *, size=-1):
-        '''
-        Return True if the column is of type type_
-
-        :param column_name: the column name
-        :param type_: the generic name of the type
-        :param size: if `type` is VARCHAR you can specify its size.
-                     Use a negative value to ignore the size check.
-                     Defaults to -1
-        :return: a boolean
-        '''
         raise NotImplementedError
 
     def db_default(self, column_name, value):
-        '''
-        Set a default on a column
-
-        :param column_name: the column name
-        :param value: the default value
-        '''
         raise NotImplementedError
 
     def add_column(self, column_name, abstract_type, default=None, comment=''):
-        '''
-        Add a column
-
-        :param column_name: the column name
-        :param abstract_type: the abstract type that will represent this column
-        :param default: the method that return default value to use
-        :param comment: An optional comment on the column
-        '''
         raise NotImplementedError
 
     def add_fk(self, column_name, reference, on_delete=None):
-        '''
-        Add a foreign key
-
-        :param column_name: the column name
-        :param reference: the foreign table name
-        :param on_delete: the "on delete" value
-        '''
         raise NotImplementedError
 
     def drop_fk(self, column_name, table=None):
-        '''
-        Drop a foreign key
-
-        :param column_name: the column name
-        :param table: optional table name
-        '''
         raise NotImplementedError
 
     def index_action(self, columns, action='add', where=None, table=None):
-        '''
-        Add/remove an index
-
-        :param columns: the column or a list of columns/expressions
-        :param action: 'add' or 'remove'
-        :param where: predicate expression
-        :param table: optional table name
-        '''
         raise NotImplementedError
 
     def not_null_action(self, column_name, action='add'):
-        '''
-        Add/remove a "not null"
-
-        :param column_name: the column name
-        :param action: 'add' or 'remove'
-        '''
         raise NotImplementedError
 
     def add_constraint(self, ident, constraint):
-        '''
-        Add a constraint
-
-        :param ident: the name of the constraint
-        :param constraint: the definition of the constraint
-        '''
         raise NotImplementedError
 
     def drop_constraint(self, ident, table=None):
-        '''
-        Remove a constraint
-
-        :param ident: the name of the constraint
-        :param table: optional table name
-        '''
         raise NotImplementedError
 
     def drop_column(self, column_name):
-        '''
-        Remove a column
-
-        :param column_name: the column name
-        '''
         raise NotImplementedError
 
-    @staticmethod
-    def drop_table(model, table, cascade=False):
-        '''
-        Remove a table and clean ir_model_data from the given model.
-
-        :param model: the model name
-        :param table: the table name
-        :param cascade: a boolean to add "CASCADE" to the delete query
-        '''
+    @classmethod
+    def drop_table(cls, model, table, cascade=False):
         raise NotImplementedError
 
     @classmethod
     def convert_name(cls, name):
-        '''
-        Convert data name in respect of namedatalen.
-
-        :param name: the data name
-        '''
         if cls.namedatalen and len(name) >= cls.namedatalen:
             if isinstance(name, str):
                 name = name.encode('utf-8')
diff -r 2f01695e906a -r 08d07aa63e73 trytond/ir/action.py
--- a/trytond/ir/action.py      Thu Sep 01 22:10:10 2022 +0200
+++ b/trytond/ir/action.py      Thu Sep 08 13:05:06 2022 +0200
@@ -398,8 +398,6 @@
             cursor.execute(*ir_action.update(
                     [ir_action.id], [action.id],
                     where=ir_action.id == record.id))
-            transaction.database.update_auto_increment(
-                transaction.connection, cls._table, action.id)
             record = cls(action.id)
             new_records.append(record)
             to_write.extend(([record], later))

Reply via email to