diff --git a/content/administration/upgrade.rst b/content/administration/upgrade.rst index 153773268f..ef35023250 100644 --- a/content/administration/upgrade.rst +++ b/content/administration/upgrade.rst @@ -39,10 +39,11 @@ An upgrade does not cover: - Migrating from another ERP to Odoo .. warning:: - If your database contains a **custom module**, you must first upgrade its source code to be - compatible with the new version of Odoo **before upgrading**. -.. TODOUPG : once the page for developers is published, uncomment and link -.. :doc:`first upgrade its source code ` + If your database contains custom modules, it cannot be upgraded until a version of your custom + modules is available for the target version of Odoo. For customers maintaining their own custom + modules, we recommend to parallelize the process by :ref:`requesting an upgraded database + ` while also :doc:`upgrading the source code of your custom + modules `. Upgrading in a nutshell @@ -51,15 +52,15 @@ Upgrading in a nutshell #. Request an upgraded test database (see :ref:`obtaining an upgraded test database `). +#. If applicable : upgrade the source code of your custom module to be compatible with the new + version of Odoo (see :doc:`/developer/howtos/upgrade_custom_db`). + #. Thoroughly test the upgraded database (see :ref:`testing the new version of the database `). #. Report any issue encountered during the testing to Odoo via the `support page `__. -#. (If applicable) : upgrade the source code of your custom module to be compatible with the new - version of Odoo. - #. Once all issues are resolved and you are confident that the upgraded database can be used as your main database without any issues, plan the upgrade of your production database. @@ -69,9 +70,6 @@ Upgrading in a nutshell #. Report any issue encountered during the upgrade to Odoo via the `support page `__. -.. TODOUPG: Once the page for developers is published, put this at 4) -.. (see :ref:`upgrading customizations `). - .. _upgrade/request-test-database: Obtaining an upgraded test database @@ -136,18 +134,16 @@ project `_. file of the upgrade process can be found in your newly upgraded staging build by going to :file:`~/logs/upgrade.log`. - .. note:: + .. important:: In databases where custom modules are installed, their source code must be up-to-date with the target version of Odoo before the upgrade can be performed. If there are none, the "update on commit" mode is skipped, the upgraded database is built as soon as it is transferred from the upgrade platform, and the upgrade mode is exited. - .. TODOUPG : once the page for developers is published, uncomment - .. Check out the :doc:`upgrade for developers' - .. documentation ` for more information. In - .. addition, if a module is not needed after an upgrade, :ref:`you can - .. remove customizations `. + Check out the :ref:`upgrading a customized database ` page for + more information. In addition, if a module is not needed after an upgrade, :ref:`you can + remove customizations `. .. group-tab:: On-premise @@ -167,6 +163,17 @@ project `_. An upgraded test database can also be requested via the `Upgrade page `_. + .. important:: + In databases where custom modules are installed, their source code + must be up-to-date with the target version of Odoo before the upgrade + can be performed. If there are none, the "update on commit" mode is + skipped, the upgraded database is built as soon as it is transferred from the upgrade + platform, and the upgrade mode is exited. + + Check out the :ref:`upgrading a customized database ` page for + more information. In addition, if a module is not needed after an upgrade, :ref:`you can + remove customizations `. + .. note:: - For security reasons, only the person who submitted the upgrade request can download it. - For storage reasons, the database's copy is submitted without a filestore to the upgrade @@ -291,8 +298,8 @@ the upgrade at a time when the use of the database is minimal. As the standard upgrade scripts and your database are constantly evolving, it is also recommended to frequently request another upgraded test database to ensure that the upgrade process is -still successful, especially if it takes a long time to finish. Fully rehearsing the upgrade -process the day before upgrading the production database is also recommended. +still successful, especially if it takes a long time to finish. **Fully rehearsing the upgrade +process the day before upgrading the production database is also recommended.** .. important:: - Going into production without first testing may lead to: @@ -338,8 +345,7 @@ exceptions. The update of your custom modules must be successful to complete the entire upgrade process. Make sure the status of your staging upgrade is :guilabel:`successful` before trying it in production. - .. TODOUPG : once the page for developers is published, uncomment - .. More information on how to upgrade your custom modules can be found in the :ref:`upgrading customizations documentation `. + More information on how to upgrade your custom modules can be found on page :ref:`upgrading a customized database `. .. group-tab:: On-premise diff --git a/content/developer/howtos.rst b/content/developer/howtos.rst index 6a38860ac3..df40ded8b7 100644 --- a/content/developer/howtos.rst +++ b/content/developer/howtos.rst @@ -20,6 +20,7 @@ How-to guides howtos/translations howtos/website_themes howtos/connect_device + howtos/upgrade_custom_db .. cards:: @@ -84,3 +85,8 @@ How-to guides :target: howtos/connect_device Learn how to enable a module to detect and communicate with an IoT device. + + .. card:: Upgrading a customized database + :target: howtos/upgrade_custom_db + + Learn how to upgrade a customized database, as well as the code and data of its custom modules. \ No newline at end of file diff --git a/content/developer/howtos/upgrade/migration_scripts.rst b/content/developer/howtos/upgrade/migration_scripts.rst new file mode 100644 index 0000000000..b2c4459536 --- /dev/null +++ b/content/developer/howtos/upgrade/migration_scripts.rst @@ -0,0 +1,139 @@ +.. _upgrade/migration-scripts: + +================= +Migration scripts +================= + +TODOUPG See comments in the code for NAMA notes (what this page should be about) + +.. #. What they are (python scripts that receives the psql cursor and the version) +.. #. What they are for : applying a modification on the data of your database when upgrading a module +.. #. In what circumstances you should use them : when changing the source code of your module between +.. 2 versions of Odoo +.. #. How to write them : examples, upgrade-util package +.. #. The different phases and what is their impact: pre no ORM, before module is loaded so before +.. your new field gets created +.. #. Where to put them : in /migration**s** +.. #. How to test them Odoo SH : branch in upgrade mode, push a commit, On-premise: receive your +.. dump, run it and upgrade all modules via starting odoo-bin + +A migration script is a Python file containing a function called `migrate`, which the upgrade +process invokes at the appropriate time. Typically, this function executes one or multiple SQL +queries and can also access Odoo's ORM, as well as the `upgrade-util package +`__. + +.. example:: + Between Odoo 15 and Odoo 16, the `sale.subscription` model was merged into the `sale.order` model + in the standard code of Odoo. This change required the development of standard migration scripts + to transfer rows from the `sale_subscription` PSQL table to the `sale_order` table, ensuring no + data is lost. Then, once the standard data has been migrated, the table `sale_subscription` gets + removed by another standard migration script. + +.. seealso:: + `DjangoProject.com documentation: Migrations + `_ + +.. spoiler:: Two migration scripts: adding "!" at the end of partners' names + + .. code-block:: python + + import logging + + _logger = logging.getLogger(__name__) + + + def migrate(cr, version): + cr.execute( + """ + UPDATE res_partner + SET name = name || '!' + """ + ) + _logger.info("Updated %s partners", cr.rowcount) + + .. code-block:: python + + import logging + from odoo.upgrade import util + + _logger = logging.getLogger(__name__) + + + def migrate(cr, version): + env = util.env(cr) + + partners = env["res.partner"].search([]) + for partner in partners: + partner.name += "!" + + _logger.info("Updated %s partners", len(partners)) + +.. spoiler:: Migration script: fixing a Studio view + + .. code-block:: python + + import logging + from odoo.upgrade import util + + _logger = logging.getLogger(__name__) + + + def migrate(cr, version): + with util.edit_view(cr, "studio_customization.odoo_studio_project__e2f15f1a-2bdb-4003-a36e-ed731a1b9fae") as arch: + node = arch.xpath("""//xpath[@expr="//group[field[@name='activity_summary']]"]""")[0] + node.attrib["expr"] = "//field[@name='activity_summary']" + +.. note:: + Only Odoo's employees can modify migration scripts in the standard upgrade process on the upgrade + server. Third-party developers can develop custom migration scripts for their custom modules. + +Positioning a migration script +------------------------------ + +Migration scripts are executed depending on their module, the version of Odoo, the version of the +module, the phase of the migration script, and its name. The path of the file should follow this +template: :file:`/migrations/./{pre|post|end}-*.py` + +- :file:`` corresponds to the folder name of a module. For example, :file:`account` for + the Accounting module, or :file:`sale_subscription` for the Subscriptions module. +- :file:`` corresponds to the major version of Odoo (e.g., :file:`16.0` for Odoo 16). +- :file:`` corresponds to the minor version of the module (e.g., :file:`1.2` for the + `Accounting module in Odoo 16 `_). +- :file:`` corresponds to :ref:`the phase of the migration script + `. +- :file:`*.py` corresponds to the name of the migration script. Its name will determine the order in + which it is executed for that module, version, and phase. + +.. _upgrade/migration-scripts-phases: + +Phases of migration scripts +--------------------------- + +The upgrade process consists of three phases for each version of each module: + + #. The pre-phase, before the module and its dependencies are loaded. The ORM is not available at + that time. + #. The post-phase, after the module and its dependencies are loaded and upgraded. + #. The end-phase, after all modules have been upgraded for that version. + +.. note:: + If you are unsure which phase to use, use the end-phase. + +Migration scripts are grouped according to the first part of their filenames into the corresponding +phase. So, for example, a file named :file:`pre-upgrade_data.py` will execute before +:file:`post-do_upgrade_data.py` regardless of their lexical order. In each phase, files are then +executed according to their lexical order. + +.. spoiler:: Execution order of example scripts for one module in one version + + - :file:`pre-zzz.py` + - :file:`pre-~do_something.py` + - :file:`post--testing.py` + - :file:`post-01-zzz.py` + - :file:`post-migrate.py` + - :file:`post-other_module.py` + - :file:`post-~migrate.py` + - :file:`end--migrate.py` + - :file:`end-01-migrate.py` + - :file:`end-aaa.py` + - :file:`end-~migrate.py` \ No newline at end of file diff --git a/content/developer/howtos/upgrade_custom_db.rst b/content/developer/howtos/upgrade_custom_db.rst new file mode 100644 index 0000000000..1fb851d651 --- /dev/null +++ b/content/developer/howtos/upgrade_custom_db.rst @@ -0,0 +1,194 @@ +:show-content: +:show-toc: + +.. _upgrade/upgrade_custom_db: + +=============================== +Upgrading a customized database +=============================== + +.. note:: + This page is intended to explain the technical aspects of upgrading a database with non-standard + modules. For a more general overview, please refer to the + :doc:`upgrade documentation `. + +Upgrading a database that contains custom modules requires additional steps compared to +databases running the standard modules of Odoo since the source code of the custom modules +must be upgraded as well. + +.. important:: + When committing to upgrading your custom database, it is crucial to halt the development of new + features since they would have to be upgraded as well, and might create new issues later during + the upgrade process. Once your upgrade is complete, you may resume their development. + +Custom modules are usually not compatible out of the box with a new version of Odoo due to changes +in the standard modules, such as models being merged, fields being renamed, or methods being +refactored. Therefore, a new version of the modules must be created for each new version +of Odoo, in which its source code is adapted to the new version. + +Our recommendation is to first assess your customization by comparing them to the features brought +by the new version of Odoo to detect any redundant customizations that can be removed from your +database, making your modules easier to maintain + +Then, make your custom modules installable on a new, empty database to ensure dependencies are +still correct, fields definitions are still valid, etc. This also require some :ref:`testing +` to ensure that all the features of your modules are still working properly. +This step is important to determine if your modules are working by themselves, and not +relying on any data or installed apps already present in the database. + +During that process, you can also :ref:`Request a test upgraded database +` to ensure the request can be successfully processed. + +Once your modules are installable and working properly (see +:ref:`Testing your database `), it is time to make them work on an upgraded +database. During this process, you might have to develop +:ref:`migration scripts ` to reflect changes in the source code of +your custom modules to their corresponding data. + +After this step, it is crucial to do another :ref:`round of testing ` to +assess your database usability, as well as to detect any issue with the migrated data. + +At this stage, the rest of the upgrade process is the same as described in :doc:`/administration/upgrade`. + +.. seealso:: + - :doc:`/developer/reference/user_interface/view_records` + - :ref:`reference/fields` + - :ref:`reference/orm/models` + - `Upgrade-util package `_ + +.. _upgrade/remove_customizations: + +Assessing your customizations +============================= + +Before upgrading your database, it is important to assess the features brought by the new version +of Odoo to determine if any of your customizations have become redundant and can be removed from +your database. + +.. example:: + In Odoo 15, the `sale.subscription` model has been merged into the `sale.order` module. Therefore, + any field added to the `sale.subscription` model must be ported over to the `sale.order` model. + Other references such as related fields, views, reports, etc., must also be updated to match the + new model name. + +Information on the changes between versions can be found in the `release notes +`_ and the :ref:`upgrade report `. + +Modules that have become redundant with the release of a new version of Odoo can be removed +from your database with a :ref:`migration script ` using the +`uninstall_module` method from the `upgrade-util package `__. + +If only a few elements of a module have become redundant, it is possible to remove them one by one +using `remove_field`, `remove_model`, `remove_view`, etc., from the +`upgrade-util package __`. + +.. warning:: + Don't forget that fields, models, and views can still be referenced in other records such as + automated and server actions, mail templates, filters, etc. . Those references must be found + and removed from the database, preferably in the same :ref:`migration script `. + +.. important:: + :ref:`Testing your database ` is crucial, especially when removing + customizations. Any customized view, report, filter, mail template, automated and server + actions, etc., referring to a missing record will prevent them from working correctly and might + block your processes in certain situations. + +Custom modules on an empty database +=================================== + +Installing custom modules on an empty database allows you to detect any discrepancies between the +source code of your modules and the new version of Odoo, such as missing dependencies in the +manifest, broken fields relations, views containing deprecated fields, etc. + +Any custom field that has a reference to a modified standard field must be adapted to the new +version of Odoo. To find the corresponding field in the new version, we recommend looking at its +properties and finding a field with matching properties. You can also use the :ref:`upgrade report +` and the `release notes `_ to support +your search. + +.. example:: + In Odoo 12 and before, the `account.invoice` model had a field named `refund_invoice_id` (`source + code `_), + which is absent on the `account.move` model after Odoo 13. This field was renamed to + `reversed_entry_id` during the upgrade process. It is possible to find this information by + searching for another Many2one field in `account.move` related to `account.move`, for example, + `in Odoo 16 `_. + +.. important:: + Renaming fields in the source code of a module will not migrate the data from the old field to + the new one. This requires writing a :ref:`migration script `. + +References to fields in server, scheduled, and automated actions might be broken due to changes in +the fields' definitions. This is usually the case for the actions :guilabel:`Execute Python Code`, :guilabel:`Create a +new Record`, or :guilabel:`Update the Record`. + +TODOUPG: can they be removed, or will they simply be archived ? + +Those actions are susceptible to being removed by the standard upgrade process, requiring +`intervention from an Odoo developer `_. Otherwise, it can be fixed +with a custom `migration script `_. + +.. seealso:: + :ref:`Server actions ` + +More rarely, models can also be renamed or merged into another model. In this case, if a custom +model inherits from the renamed or merged model, its inherit attributes must be updated to match the +new model name. + +.. example:: + - Between Odoo 12 and 13, the `account.invoice` model was merged into `account.move`. + - Between Odoo 15 and 16, the `sale.subscription` model was merged into `sale.order`. + - Between Odoo 15 and 16, the `account.analytic.group` model was renamed to `account.analytic.plan`. + +If a custom model overrides standard methods, you must ensure that their name still matches the +name of the method they are overriding. In case of changes, you can search the method's source code +in the new version to find its new name. If the method has been refactored, the source code might +not exactly match, and a manual search is then required. The same goes for function calls to those methods. + +.. example:: + The `sale.subscription` model has a `_prepare_invoice_data` method `in Odoo 15 + `_ + that has been moved and renamed to `_prepare_invoice` in the `sale.order` model `of Odoo 16 + `_. + +Custom views are usually also impacted with the upgrade, as they may refer fields, models, or +other standard views that have been renamed or refactored. They should be adapted to the new +version of Odoo to avoid errors when loading them. + +Once the source code of the custom modules has been upgraded, it is time to test them on a new +database to ensure that they does not depend on a previous installation (e.g., modules +already installed, data already present, etc.). This testing can help you detect issues with +your modules' dependencies, computed fields, etc. + +.. seealso:: + :ref:`Testing your database ` + +Custom modules on an upgraded database +====================================== + +Reaching this step requires both the source code of your custom modules to be upgraded and a +successful :ref:`upgrade request `. If that is the case, you can +now test your modules on an upgraded database to ensure that the upgrade did not remove any +data, and that your modules are still working properly. + +When renaming fields in the process of upgrading the source code of your custom modules, the data +from the old field must be migrated to the new one. This can be done via a :ref:`migration script +` using the `rename_field` method from the +`upgrade-util package `__. +However, this only renames the field and column names. Therefore, custom views, reports, field +relations, automated actions, etc., might still refer to the old field name and need to be +updated in the :ref:`migration script ` as well. + +This is why it is crucial to do another :ref:`round of testing ` to ensure +that no data has been lost due to the upgrade of your custom modules. + +Rehearsal, testing, and production upgrade +========================================== + +At this stage, we recommend to do a rehearsal upgrade on a copy of your production database to +ensure that the upgrade process is still working as expected, especially if you haven't done an +upgrade request in a while. + +Once you are confident that upgrading your database will not cause any issue, you can proceed with +the upgrade of your production database by following the process described on the +:doc:`/administration/upgrade` page. \ No newline at end of file diff --git a/content/developer/reference/backend.rst b/content/developer/reference/backend.rst index cd56eca9c8..e9cc71870d 100644 --- a/content/developer/reference/backend.rst +++ b/content/developer/reference/backend.rst @@ -17,3 +17,4 @@ Python framework backend/testing backend/http backend/mixins + backend/migration_scripts diff --git a/content/developer/reference/backend/migration_scripts.rst b/content/developer/reference/backend/migration_scripts.rst new file mode 100644 index 0000000000..3c281d52c1 --- /dev/null +++ b/content/developer/reference/backend/migration_scripts.rst @@ -0,0 +1,134 @@ +.. _upgrade/migration-scripts: + +================= +Migration scripts +================= + +TODOUPG See comments in the code for NAMA notes (what this page should be about) + +.. #. What they are (python scripts that receives the psql cursor and the version) +.. #. What they are for : applying a modification on the data of your database when upgrading a module +.. #. In what circumstances you should use them : when changing the source code of your module between +.. 2 versions of Odoo +.. #. How to write them : examples, upgrade-util package +.. #. The different phases and what is their impact: pre no ORM, before module is loaded so before +.. your new field gets created +.. #. Where to put them : in /migration**s** +.. #. How to test them Odoo SH : branch in upgrade mode, push a commit, On-premise: receive your +.. dump, run it and upgrade all modules via starting odoo-bin + +A migration script is a Python file containing a function called `migrate`, which the upgrade +process invokes at the appropriate time. Typically, this function executes one or multiple SQL +queries and can also access Odoo's ORM, as well as the `upgrade-util package +`__. + +.. example:: + Between Odoo 15 and Odoo 16, the `sale.subscription` model was merged into the `sale.order` model + in the standard code of Odoo. This change required the development of standard migration scripts + to transfer rows from the `sale_subscription` PSQL table to the `sale_order` table, ensuring no + data is lost. Then, once the standard data has been migrated, the table `sale_subscription` gets + removed by another standard migration script. + +.. seealso:: + `DjangoProject.com documentation: Migrations + `_ + +.. spoiler:: Two migration scripts: adding "!" at the end of partners' names + + .. code-block:: python + + import logging + + _logger = logging.getLogger(__name__) + + + def migrate(cr, version): + cr.execute( + """ + UPDATE res_partner + SET name = name || '!' + """ + ) + _logger.info("Updated %s partners", cr.rowcount) + + .. code-block:: python + + import logging + from odoo.upgrade import util + + _logger = logging.getLogger(__name__) + + + def migrate(cr, version): + env = util.env(cr) + + partners = env["res.partner"].search([]) + for partner in partners: + partner.name += "!" + + _logger.info("Updated %s partners", len(partners)) + +.. spoiler:: Migration script: renaming a field + + .. code-block:: python + + import logging + from odoo.upgrade import util + + _logger = logging.getLogger(__name__) + + + def migrate(cr, version): + util.rename_field(cr, "account.analytic.line", "analytic_group", "analytic_plan_id") + + +Positioning a migration script +------------------------------ + +Migration scripts are executed depending on their module, the version of Odoo, the version of the +module, the phase of the migration script, and its name. The path of the file should follow this +template: :file:`/migrations/./{pre|post|end}-*.py` + +- :file:`` corresponds to the folder name of a module. For example, :file:`account` for + the Accounting module, or :file:`sale_subscription` for the Subscriptions module. +- :file:`` corresponds to the major version of Odoo (e.g., :file:`16.0` for Odoo 16). +- :file:`` corresponds to the minor version of the module (e.g., :file:`1.2` for the + `Accounting module in Odoo 16 `_). +- :file:`` corresponds to :ref:`the phase of the migration script + `. +- :file:`*.py` corresponds to the name of the migration script. Its name will determine the order in + which it is executed for that module, version, and phase. + +.. _upgrade/migration-scripts-phases: + +Phases of migration scripts +--------------------------- + +The upgrade process consists of three phases for each version of each module: + + #. The pre-phase, before the module and its dependencies are loaded. The ORM is not available at + that time. + #. The post-phase, after the module and its dependencies are loaded and upgraded. + #. The end-phase, after all modules have been upgraded for that version. + +.. note:: + If you are unsure which phase to use, use the end-phase. + +Migration scripts are grouped according to the first part of their filenames into the corresponding +phase. So, for example, a file named :file:`pre-upgrade_data.py` will execute before +:file:`post-do_upgrade_data.py` regardless of their lexical order. In each phase, files are then +executed according to their lexical order. + +.. spoiler:: Execution order of example scripts for one module in one version + + - :file:`pre-zzz.py` + - :file:`pre-~do_something.py` + - :file:`post--testing.py` + - :file:`post-01-zzz.py` + - :file:`post-migrate.py` + - :file:`post-other_module.py` + - :file:`post-~migrate.py` + - :file:`end--migrate.py` + - :file:`end-01-migrate.py` + - :file:`end-aaa.py` + - :file:`end-~migrate.py` \ No newline at end of file diff --git a/content/developer/reference/cli.rst b/content/developer/reference/cli.rst index dcfef28f58..bd8c3c60cf 100644 --- a/content/developer/reference/cli.rst +++ b/content/developer/reference/cli.rst @@ -136,13 +136,9 @@ Running the server stops the server after its initialization. -.. option:: --geoip-city-db +.. option:: --geoip-db - Absolute path to the GeoIP City database file. - -.. option:: --geoip-country-db - - Absolute path to the GeoIP Country database file. + Absolute path to the GeoIP database file. .. _reference/cmdline/testing: @@ -290,7 +286,7 @@ Database .. option:: --unaccent - Try to enable the unaccent extension when creating new databases + Use the unaccent function provided by the database when available. .. _reference/cmdline/server/emails: @@ -559,18 +555,18 @@ Multiprocessing .. option:: --limit-memory-soft - Maximum allowed virtual memory per worker in bytes. If the limit is exceeded, + Maximum allowed virtual memory per worker. If the limit is exceeded, the worker is killed and recycled at the end of the current request. - Defaults to *2048MiB (2048\*1024\*1024B)*. + Defaults to *2048MiB*. .. option:: --limit-memory-hard - Hard limit on virtual memory in bytes, any worker exceeding the limit will be + Hard limit on virtual memory, any worker exceeding the limit will be immediately killed without waiting for the end of the current request processing. - Defaults to *2560MiB (2560\*1024\*1024B)*. + Defaults to *2560MiB*. .. option:: --limit-time-cpu @@ -655,9 +651,8 @@ Here is a sample file: Shell ===== -Odoo command-line also allows to launch odoo as a python console environment. -This enables direct interaction with the :ref:`orm ` and its functionalities. - +The Odoo command line also allows launching Odoo as a Python console environment, enabling direct +interaction with the :ref:`orm ` and its functionalities. .. code-block:: console @@ -665,8 +660,32 @@ This enables direct interaction with the :ref:`orm ` and its func .. option:: --shell-interface (ipython|ptpython|bpython|python) - Specify a preferred REPL to use in shell mode. + Specify a preferred REPL to use in shell mode. This shell is started with the `env` variable + already initialized to be able to access the ORM and other Odoo modules. + +.. example:: Example of shell usage + + Adding an exclamation mark to all contacts' names: + + .. code-block:: python + In [1]: records = env["res.partner"].search([]) + + In [2]: records + Out[2]: res.partner(14, 26, 33, 21, 10) + + In [3]: for partner in records: + ...: partner.name = "%s !" % partner.name + ...: + + In [4]: env.cr.commit() + + .. important:: + By default, the shell is running in transaction mode. This means that any change made to the + database is rolled back when exiting the shell. To commit changes, use `env.cr.commit()`. + +.. seealso:: + :ref:`Environment documentation ` .. _reference/cmdline/scaffold: @@ -906,4 +925,4 @@ containing community and enterprise. .. code-block:: console - $ community/odoo-bin tsconfig --addons-path community/addons,community/odoo/addons,enterprise > tsconfig.json + $ community/odoo-bin tsconfig --addons-path community/addons,community/odoo/addons,enterprise > tsconfig.json \ No newline at end of file