Skip to content

Commit 3139eaf

Browse files
committed
[ADD] Upgrade documentation: Upgrade scripts and Util package
closes #7547 X-original-commit: 16a209c Signed-off-by: Antoine Vandevenne (anv) <[email protected]>
1 parent 58365b7 commit 3139eaf

File tree

4 files changed

+456
-19
lines changed

4 files changed

+456
-19
lines changed

content/developer/howtos/upgrade_custom_db.rst

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ These are the steps to follow to upgrade customized databases:
3333
#. :ref:`Test extensively and do a rehearsal <upgrade_custom/testing_rehearsal>`.
3434
#. :ref:`Upgrade the production database <upgrade_custom/production>`.
3535

36-
3736
.. _upgrade_custom/stop_developments:
3837

3938
Step 1: Stop the developments
@@ -47,14 +46,13 @@ Needless to say, bug fixing is exempt from this recommendation.
4746
Once you have stopped development, it is a good practice to assess the developments made and compare
4847
them with the features introduced between your current version and the version you are targeting.
4948
Challenge the developments as much as possible and find functional workarounds. Removing redundancy
50-
between your developments and the standard version of Odoo will lead to an eased
51-
upgrade process and reduce technical debt.
49+
between your developments and the standard version of Odoo will lead to an eased upgrade process
50+
and reduce technical debt.
5251

5352
.. note::
5453
You can find information on the changes between versions in the `Release Notes
5554
<https:/odoo.com/page/release-notes>`_.
5655

57-
5856
.. _upgrade_custom/request_upgrade:
5957

6058
Step 2: Request an upgraded database
@@ -71,7 +69,6 @@ properly. If that's not the case, and the upgrade request fails, request the ass
7169
the `support page <https://odoo.com/help?stage=migration>`_ by selecting the option related to
7270
testing the upgrade.
7371

74-
7572
.. _upgrade_custom/empty_database:
7673

7774
Step 3: Empty database
@@ -85,7 +82,7 @@ features, and guarantees that they will not cause any issues when upgrading the
8582
Making the custom modules work in an empty database also helps avoid changes and wrong
8683
configurations that might be present in the production database (like studio customization,
8784
customized website pages, email templates or translations). They are not intrinsically related to
88-
the custom modules and that can raise unwanted issues in this stage of the upgraded process.
85+
the custom modules and that can raise unwanted issues in this stage of the upgrade process.
8986

9087
To make custom modules work on an empty database we advise to follow these steps:
9188

@@ -190,24 +187,84 @@ To make sure the custom code is working flawlessly in the new version, follow th
190187
Migrate the data
191188
----------------
192189

193-
During the upgrade of the custom modules, you might have to use migration scripts to reflect changes
194-
from the source code to their corresponding data.
190+
During the upgrade of the custom modules, you might have to use
191+
:doc:`upgrade scripts <../reference/upgrade_scripts>` to reflect changes from the source code
192+
to their corresponding data. Together with the upgrade scripts, you can also make use of the
193+
:doc:`../reference/upgrade_utils` and its helper functions.
195194

196195
- Any technical data that was renamed during the upgrade of the custom code (models, fields,
197-
external identifiers) should be renamed using migration scripts to avoid data loss during the
198-
module upgrade.
196+
external identifiers) should be renamed using upgrade scripts to avoid data loss during the
197+
module upgrade. See also: :meth:`rename_field`, :meth:`rename_model`, :meth:`rename_xmlid`.
199198
- Data from standard models removed from the source code of the newer Odoo version and from the
200199
database during the standard upgrade process might need to be recovered from the old model table
201200
if it is still present.
202201

203-
Migration scripts can also be used to:
202+
.. example::
203+
Custom fields for model ``sale.subscription`` are not automatically migrated from Odoo 15 to
204+
Odoo 16 (when the model was merged into ``sale.order``). In this case, a SQL query can be
205+
executed on an upgrade script to move the data from one table to the other. Take into account
206+
that all columns/fields must already exist, so consider doing this in a ``post-`` script (See
207+
:ref:`upgrade-scripts/phases`).
208+
209+
.. spoiler::
210+
211+
.. code-block:: python
212+
213+
def migrate(cr, version):
214+
cr.execute(
215+
"""
216+
UPDATE sale_order so
217+
SET custom_field = ss.custom_field
218+
FROM sale_subscription ss
219+
WHERE ss.new_sale_order_id = so.id
220+
"""
221+
)
222+
223+
Check the documentation for more information on :doc:`../reference/upgrade_scripts`.
224+
225+
Upgrade scripts can also be used to:
204226

205227
- Ease the processing time of an upgrade. For example, to store the value of computed stored fields
206228
on models with an excessive number of records by using SQL queries.
207-
- Recompute fields in case the computation of their value has changed.
208-
- Uninstall unwanted custom modules.
229+
- Recompute fields in case the computation of their value has changed. See also
230+
:meth:`recompute_fields`.
231+
- Uninstall unwanted custom modules. See also :meth:`remove_module`.
209232
- Correct faulty data or wrong configurations.
210233

234+
Running and testing upgrade scripts
235+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
236+
237+
.. tabs::
238+
239+
.. group-tab:: Odoo Online
240+
241+
As the instalation of custom modules containing Python files is not allowed on Odoo Online
242+
databases, it is not possible to run upgrade scripts on this platform.
243+
244+
.. group-tab:: Odoo.sh
245+
246+
As explained on the `Odoo.sh` tab of :ref:`upgrade/request-test-database`, Odoo.sh is
247+
integrated with the upgrade platform.
248+
249+
Once the upgrade of a staging branch is on "Update on commit" mode, each time a commit is
250+
pushed on the branch, the upgraded backup is restored and all the custom modules are updated.
251+
This update includes the execution of the upgrade scripts.
252+
253+
When upgrading the production database, the execution of the upgrade scripts is also part of
254+
the update of the custom modules done by the platform when the upgraded database is restored.
255+
256+
.. group-tab:: On-premise
257+
258+
Once you receive the upgraded dump of the database from the `Upgrade platform
259+
<https://upgrade.odoo.com>`_, deploy the database and update all the custom modules by
260+
invoking the command :doc:`odoo-bin </developer/reference/cli>` in the shell.
261+
To update the custom modules, use the option: `-u <modules>,
262+
--update <modules>`.
263+
264+
.. important::
265+
As mentioned in the :doc:`CLI documentation </developer/reference/cli>`, the command used
266+
to call the CLI depends on how you installed Odoo.
267+
211268
.. _upgrade_custom/upgraded_database/test_custom:
212269

213270
Test the custom modules
@@ -221,13 +278,12 @@ Things to pay attention to:
221278

222279
- Views not working: During the upgrade, if a view causes issues because of its content, it gets
223280
disabled. You can find the information on disabled views on the :ref:`Upgrade report
224-
<upgrade/upgrade_report>`. This view needs to be activated again. To achieve this, we recommend
225-
the use of migration scripts.
281+
<upgrade/upgrade_report>`. This view needs to be activated again (or removed if not useful anymore).
282+
To achieve this, we recommend the use of upgrade scripts.
226283
- :doc:`Module data <../tutorials/define_module_data>` not updated: Custom records that have the
227284
``noupdate`` flag are not updated when upgrading the module in the new database. For the custom
228-
data that needs to be updated due to changes in the new version, we recommend to use migration
229-
scripts to do so.
230-
285+
data that needs to be updated due to changes in the new version, we recommend to use upgrade
286+
scripts to do so. See also: :meth:`update_record_from_xml`.
231287

232288
.. _upgrade_custom/testing_rehearsal:
233289

@@ -247,7 +303,6 @@ In addition to that, make a full rehearsal of the upgrade process the day before
247303
production database to avoid undesired behavior during the upgrade and to detect any issue that
248304
might have occurred with the migrated data.
249305

250-
251306
.. _upgrade_custom/production:
252307

253308
Step 6: Production upgrade

content/developer/reference.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,7 @@ Reference
1212
reference/user_interface
1313
reference/standard_modules
1414
reference/cli
15+
reference/upgrade_scripts
16+
reference/upgrade_utils
1517
reference/external_api
1618
reference/extract_api
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
===============
2+
Upgrade scripts
3+
===============
4+
5+
An upgrade script is a Python file containing a function called :meth:`migrate`, which the upgrade
6+
process invokes during the update of a module.
7+
8+
.. method:: migrate(cr, version)
9+
10+
:param cr: current database cursor
11+
:type cr: :class:`~odoo.sql_db.Cursor`
12+
:param str version: installed version of the module
13+
14+
Typically, this function executes one or multiple SQL queries and can also access Odoo's ORM, as
15+
well as the :doc:`./upgrade_utils`.
16+
17+
Writing upgrade scripts
18+
=======================
19+
20+
Upgrade scripts follow a specific tree structure with a naming convention which determines when they
21+
are executed.
22+
23+
The structure of an upgrade script path is :file:`$module/migrations/$version/{pre,post,end}-*.py`,
24+
where `$module` is the module for which the script will run, `$version` is the full version of the
25+
module (including Odoo's major version and the module's minor version) and `{pre|post|end}-*.py` is
26+
the file that needs to be executed. The file's name will determine the :ref:`phase
27+
<upgrade-scripts/phases>` and order in which it is executed for that module and version.
28+
29+
.. note::
30+
Upgrade scripts are only executed when the module is being updated. Therefore, the
31+
module's minor version set in the `$version` directory needs to be higher than the module's
32+
installed version and equal or lower to the updated version of the module.
33+
34+
.. example::
35+
36+
Directory structure of an upgrade script for a custom module named `awesome_partner` upgraded
37+
to version `2.0` on Odoo 17.
38+
39+
.. code-block:: text
40+
41+
awesome_partner/
42+
|-- migrations/
43+
| |-- 17.0.2.0/
44+
| | |-- pre-exclamation.py
45+
46+
Two upgrade scripts examples with the content of the :file:`pre-exclamation.py`, file adding
47+
"!" at the end of partners' names:
48+
49+
.. code-block:: python
50+
51+
import logging
52+
53+
_logger = logging.getLogger(__name__)
54+
55+
56+
def migrate(cr, version):
57+
cr.execute("UPDATE res_partner SET name = name || '!'")
58+
_logger.info("Updated %s partners", cr.rowcount)
59+
60+
.. code-block:: python
61+
62+
import logging
63+
from odoo.upgrade import util
64+
65+
_logger = logging.getLogger(__name__)
66+
67+
68+
def migrate(cr, version):
69+
env = util.env(cr)
70+
71+
partners = env["res.partner"].search([])
72+
for partner in partners:
73+
partner.name += "!"
74+
75+
_logger.info("Updated %s partners", len(partners))
76+
77+
Note that in the second example, the script takes advantage of the :doc:`./upgrade_utils` to
78+
access the ORM. Check the documentation to find out more about this library.
79+
80+
.. _upgrade-scripts/phases:
81+
82+
Phases of upgrade scripts
83+
=========================
84+
85+
The upgrade process consists of three phases for each version of each module:
86+
87+
#. The pre-phase, before the module is loaded.
88+
#. The post-phase, after the module and its dependencies are loaded and updated.
89+
#. The end-phase, after all modules have been loaded and updated for that version.
90+
91+
Upgrade scripts are grouped according to the first part of their filenames into the corresponding
92+
phase. Within each phase, the files are executed according to their lexical order.
93+
94+
.. admonition:: Execution order of example scripts for one module in one version
95+
96+
#. :file:`pre-10-do_something.py`
97+
#. :file:`pre-20-something_else.py`
98+
#. :file:`post-do_something.py`
99+
#. :file:`post-something.py`
100+
#. :file:`end-01-migrate.py`
101+
#. :file:`end-migrate.py`

0 commit comments

Comments
 (0)