Skip to content

Commit 03ea36f

Browse files
committed
[ADD] Upgrade documentation technical
1 parent 784dea6 commit 03ea36f

File tree

5 files changed

+463
-427
lines changed

5 files changed

+463
-427
lines changed

content/developer/howtos.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ How-to guides
2020
howtos/translations
2121
howtos/website_themes
2222
howtos/connect_device
23+
howtos/upgrade_module
2324

2425
.. cards::
2526

@@ -84,3 +85,8 @@ How-to guides
8485
:target: howtos/connect_device
8586

8687
Learn how to enable a module to detect and communicate with an IoT device.
88+
89+
.. card:: Upgrade a custom module
90+
:target: howtos/upgrade_module
91+
92+
Learn how to upgrade a custom module to a new version of Odoo.
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
2+
=================
3+
Migration scripts
4+
=================
5+
6+
A migration script is a Python file containing a function called `migrate`, which the upgrade
7+
process invokes at the appropriate time. Typically, this function executes one or multiple SQL
8+
queries and can also access Odoo's ORM, as well as the `upgrade-util package
9+
<https://github.com/odoo/upgrade-util/>`__.
10+
11+
.. example::
12+
Between Odoo 15 and Odoo 16, the `sale.subscription` model was merged into the `sale.order` model
13+
in the standard code of Odoo. This change required the development of standard migration scripts
14+
to transfer rows from the `sale_subscription` PSQL table to the `sale_order` table, ensuring no
15+
data is lost. Then, once the standard data has been migrated, the table `sale_subscription` gets
16+
removed by another standard migration script.
17+
18+
.. seealso::
19+
`DjangoProject.com documentation: Migrations
20+
<https://docs.djangoproject.com/en/4.2/topics/migrations/>`_
21+
22+
.. spoiler:: Two migration scripts: adding "!" at the end of partners' names
23+
24+
.. code-block:: python
25+
26+
import logging
27+
28+
_logger = logging.getLogger(__name__)
29+
30+
31+
def migrate(cr, version):
32+
cr.execute(
33+
"""
34+
UPDATE res_partner
35+
SET name = name || '!'
36+
"""
37+
)
38+
_logger.info("Updated %s partners", cr.rowcount)
39+
40+
.. code-block:: python
41+
42+
import logging
43+
from odoo.upgrade import util
44+
45+
_logger = logging.getLogger(__name__)
46+
47+
48+
def migrate(cr, version):
49+
env = util.env(cr)
50+
51+
partners = env["res.partner"].search([])
52+
for partner in partners:
53+
partner.name += "!"
54+
55+
_logger.info("Updated %s partners", len(partners))
56+
57+
.. spoiler:: Migration script: fixing a Studio view
58+
59+
.. code-block:: python
60+
61+
import logging
62+
from odoo.upgrade import util
63+
64+
_logger = logging.getLogger(__name__)
65+
66+
67+
def migrate(cr, version):
68+
with util.edit_view(cr, "studio_customization.odoo_studio_project__e2f15f1a-2bdb-4003-a36e-ed731a1b9fae") as arch:
69+
node = arch.xpath("""//xpath[@expr="//group[field[@name='activity_summary']]"]""")[0]
70+
node.attrib["expr"] = "//field[@name='activity_summary']"
71+
72+
.. note::
73+
Only Odoo's employees can modify migration scripts in the standard upgrade process on the upgrade
74+
server. Third-party developers can develop custom migration scripts for their custom modules.
75+
76+
Positioning a migration script
77+
------------------------------
78+
79+
Migration scripts are executed depending on their module, the version of Odoo, the version of the
80+
module, the phase of the migration script, and its name. The path of the file should follow this
81+
template: :file:`<module_name>/migrations/<major_version>.<minor_version>/{pre|post|end}-*.py`
82+
83+
- :file:`<module_name>` corresponds to the folder name of a module. For example, :file:`account` for
84+
the Accounting module, or :file:`sale_subscription` for the Subscriptions module.
85+
- :file:`<major_version>` corresponds to the major version of Odoo (e.g., :file:`16.0` for Odoo 16).
86+
- :file:`<minor_version>` corresponds to the minor version of the module (e.g., :file:`1.2` for the
87+
`Accounting module in Odoo 16 <https://github.com/odoo/odoo/blob/c8a738610778d110734ca5b9b9cfe8723f70f8ce/addons/account/__manifest__.py#L5C17-L5C22>`_).
88+
- :file:`<pre|post|end>` corresponds to :ref:`the phase of the migration script
89+
<upgrade/migration-scripts-phases>`.
90+
- :file:`*.py` corresponds to the name of the migration script. Its name will determine the order in
91+
which it is executed for that module, version, and phase.
92+
93+
.. _upgrade/migration-scripts-phases:
94+
95+
Phases of migration scripts
96+
---------------------------
97+
98+
The upgrade process consists of three phases for each version of each module:
99+
100+
#. The pre-phase, before the module and its dependencies are loaded. The ORM is not available at
101+
that time.
102+
#. The post-phase, after the module and its dependencies are loaded and upgraded.
103+
#. The end-phase, after all modules have been upgraded for that version.
104+
105+
.. note::
106+
If you are unsure which phase to use, use the end-phase.
107+
108+
Migration scripts are grouped according to the first part of their filenames into the corresponding
109+
phase. So, for example, a file named :file:`pre-upgrade_data.py` will execute before
110+
:file:`post-do_upgrade_data.py` regardless of their lexical order. In each phase, files are then
111+
executed according to their lexical order.
112+
113+
.. spoiler:: Execution order of example scripts for one module in one version
114+
115+
- :file:`pre-zzz.py`
116+
- :file:`pre-~do_something.py`
117+
- :file:`post--testing.py`
118+
- :file:`post-01-zzz.py`
119+
- :file:`post-migrate.py`
120+
- :file:`post-other_module.py`
121+
- :file:`post-~migrate.py`
122+
- :file:`end--migrate.py`
123+
- :file:`end-01-migrate.py`
124+
- :file:`end-aaa.py`
125+
- :file:`end-~migrate.py`
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
2+
========================
3+
Upgrading customizations
4+
========================
5+
6+
The source code of custom modules maintained by third parties must be upgraded to be compatible with
7+
each new version of Odoo. This usually requires a static analysis of the code to find all the
8+
references of deprecated elements. However, it can also be done by installing the module and fixing
9+
the errors that occur during the installation.
10+
11+
Information on the changes between versions can be found in the `release notes
12+
<https:/odoo.com/page/release-notes>`_ and the :ref:`upgrade report <upgrade/upgrade_report>`.
13+
14+
.. seealso::
15+
- :ref:`reference/views`
16+
- :ref:`reference/fields`
17+
- :ref:`reference/orm/models`
18+
19+
.. _upgrade/comparing_customizations:
20+
21+
Comparing customizations to the new version
22+
-------------------------------------------
23+
24+
As many new features are added with each new version, some customizations may become obsolete when
25+
equivalent features become part of the standard version of Odoo.
26+
27+
Therefore, exploring the new features and comparing them with your customizations is recommended.
28+
Removing unnecessary customizations reduces the work needed to maintain and upgrade your database.
29+
30+
.. _upgrade/remove_customizations:
31+
32+
Removing customizations
33+
-----------------------
34+
35+
Customizations that have become redundant with the release of a new version of Odoo can be removed
36+
from your database with a :ref:`migration script <reference/upgrade/migration-scripts>` using the
37+
`uninstall_module` method from the `upgrade-util package <https://github.com/odoo/upgrade-util/blob/master/src/util/modules.py#L71>`__.
38+
This method renames the field and the column in the database but does not impact views, reports,
39+
filters, mail templates, automated and server actions, etc., that refer to those fields. Those
40+
references must be found and removed from the database, as well as in the same migration script.
41+
42+
.. important::
43+
:ref:`Testing your database <upgrade/test_your_db>` is crucial, especially when uninstalling a
44+
custom module. Any customized view, report, filter, mail template, automated and server actions,
45+
etc., referring to an uninstall field will prevent them from working correctly and might block
46+
your processes in certain situations.
47+
48+
.. seealso::
49+
:ref:`upgrade/comparing_customizations`
50+
51+
Upgrading custom fields and their data
52+
--------------------------------------
53+
54+
Any custom field that has a reference to a modified standard field must be adapted to the new
55+
version of Odoo. To find the corresponding field in the new version, we recommend looking at its
56+
properties and finding a field with matching properties. You can also use the :ref:`upgrade report
57+
<upgrade/upgrade_report>` and the `release notes <https:/odoo.com/page/release-notes>`_ to support
58+
your search.
59+
60+
.. example::
61+
In Odoo 12 and before, the `account.invoice` model had a field named `refund_invoice_id` (`source
62+
code <https://github.com/odoo/odoo/blob/f7431b180834a73fe8d3aed290c275cc6f8dfa31/addons/account/models/account_invoice.py#L273>`_),
63+
which is absent on the `account.move` model after Odoo 13. This field was renamed to
64+
`reversed_entry_id` during the upgrade process. It is possible to find this information by
65+
searching for another Many2one field in `account.move` related to `account.move`, for example,
66+
`in Odoo 16 <https://github.com/odoo/odoo/blob/a0c1e2aa602ae46598a350ea6ae8d8b4a0c1c823/addons/account/models/account_move.py#L453>`_.
67+
68+
.. note::
69+
Renaming fields can be done with the `rename_field` method from `the upgrade-util package <https://github.com/odoo/upgrade-util/blob/220114f217f8643f5c28b681fe1a7e2c21449a03/src/util/fields.py#L336>`_.
70+
However, this only renames the field and column names. Therefore, custom views, reports, field
71+
relations, automated actions, etc., might still refer to the old field name and need to be
72+
updated in the migration script as well.
73+
74+
Upgrading models and methods definitions
75+
----------------------------------------
76+
77+
Upgrading custom models consists mainly of ensuring that the module name and its inheritances
78+
are correct. The :ref:`upgrade report <upgrade/upgrade_report>` and the `release notes
79+
<https:/odoo.com/page/release-notes>`_ can contain helpful information concerning various standard
80+
models being changed or renamed.
81+
82+
.. example::
83+
The `sale.subscription` model has a `_prepare_invoice_data` method `in Odoo 15 <https://github.com/odoo/enterprise/blob/e07fd8650246d52c7289194dbe2b15b22c6b65e0/partner_commission/models/sale_subscription.py#L86-L92>`_
84+
that has been moved and renamed to `_prepare_invoice` in the `sale.order` model `of Odoo 16 <https://github.com/odoo/enterprise/blob/b4182d863a3b925dc3fe082484c27dbb1f2a57d8/partner_commission/models/sale_order.py#L62-L68>`_.
85+
86+
If a custom model overrides standard methods, you must ensure that their name still matches the
87+
name of the method they are overriding. In case of changes, you can search the method's source code
88+
in the new version to find its new name. If the method has been refactored, the source code might
89+
not exactly match, and a manual search is then required.
90+
91+
Upgrading views definitions
92+
---------------------------
93+
94+
Views defined in Odoo have an external identifier corresponding to the `id` attribute of a view's
95+
`<record/>` tag, which can happen during a module update or when rendering it.
96+
97+
Most of the time, the incompatibility of a custom view is expressed via an error when parsing the
98+
view, which can happen during the update of a module or when rendering it.
99+
100+
Custom views for custom models only require upgrading if the custom model has been changed. In
101+
contrast, custom views inheriting from standard views can be impacted by changes in the standard
102+
views. In this case, the custom views' source code requires an upgrade to be compatible with the new
103+
version of its parent view. This can be done by retargetting the various Xpath expressions to match
104+
an equivalent element that might have been moved or renamed.

0 commit comments

Comments
 (0)