Skip to content

Commit 4475084

Browse files
yajoaj-fuentes
andcommitted
[IMP] Helper to preserve all translated fields on v16 migration
Currently, the upgrade process preserves translations only for Odoo CE+EE fields. However, databases usually have more modules (or even custom fields) and those translations get lost when upgrading to Odoo 16. Running this script in a migrated database, all translated fields will inherit their translations in all languages. @moduon MT-7120 Co-authored-by: Alvaro Fuentes <[email protected]>
1 parent c47b904 commit 4475084

File tree

1 file changed

+83
-3
lines changed

1 file changed

+83
-3
lines changed

src/util/specific.py

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
# -*- coding: utf-8 -*-
22
import logging
33

4+
from .exceptions import UpgradeError
45
from .helpers import _validate_table
5-
from .misc import _cached
6+
from .misc import _cached, version_gte
67
from .models import rename_model
7-
from .modules import rename_module
8-
from .pg import column_exists, rename_table, table_exists
8+
from .modules import odoo, rename_module
9+
from .orm import env
10+
from .pg import column_exists, format_query, parallel_execute, rename_table, table_exists
911
from .report import add_to_migration_reports
1012

1113
_logger = logging.getLogger(__name__)
@@ -137,3 +139,81 @@ def reset_cowed_views(cr, xmlid, key=None):
137139
[key, module, name],
138140
)
139141
return set(sum(cr.fetchall(), ()))
142+
143+
144+
def translation2jsonb_all_missing(cr):
145+
"""Convert all missing translated fields to jsonb.
146+
147+
This helper function is designed to run only in an on-premise Odoo instance
148+
where any unofficial modules you use are installed, after going through the
149+
upgrade to version 16.0.
150+
151+
It will find all unofficial fields and convert translations from the
152+
``_ir_translation`` table into the new JSONB format.
153+
154+
Modules must be available in the environment to be loaded.
155+
156+
:return: Converted fields.
157+
"""
158+
if not version_gte("16.0"):
159+
raise UpgradeError("JSONB translations are only available from Odoo 16")
160+
_env = env(cr)
161+
fields = []
162+
cr.execute(
163+
"""
164+
SELECT STRING_TO_ARRAY(name, ','),
165+
ARRAY_AGG(DISTINCT lang)
166+
FROM _ir_translation
167+
WHERE type IN ('model', 'model_terms')
168+
AND name LIKE '%,%'
169+
AND lang != 'en_US'
170+
GROUP BY name
171+
"""
172+
)
173+
for (mname, fname), langs in cr.fetchall():
174+
try:
175+
model = _env[mname]
176+
field = model._fields[fname]
177+
except KeyError:
178+
continue
179+
if (
180+
not model._auto
181+
or model._abstract
182+
or model._transient
183+
or not field.store
184+
or not field.translate
185+
or field.manual
186+
):
187+
continue
188+
# Check if the field is already converted
189+
cr.execute(
190+
format_query(cr, "SELECT 1 FROM {} WHERE {} ?| %s LIMIT 1", model._table, fname),
191+
[langs],
192+
)
193+
if not cr.rowcount:
194+
fields.append(field)
195+
return translation2jsonb(cr, *fields)
196+
197+
198+
def translation2jsonb(cr, *fields):
199+
"""Convert selected translated fields to jsonb.
200+
201+
Migrates translations for chosen fields, from the ``_ir_translation`` table
202+
into the new JSONB format.
203+
204+
:param odoo.fields.Field fields: Fields to convert.
205+
:return: Converted fields.
206+
"""
207+
if not version_gte("16.0"):
208+
raise UpgradeError("JSONB translations are only available from Odoo 16")
209+
all_cleanup_queries = []
210+
for field in fields:
211+
_logger.info("Migrating translations for field %s in model %s", field.name, field.model_name)
212+
(
213+
migrate_queries,
214+
cleanup_queries,
215+
) = odoo.tools.translate._get_translation_upgrade_queries(cr, field)
216+
all_cleanup_queries.extend(cleanup_queries)
217+
parallel_execute(cr, migrate_queries)
218+
parallel_execute(cr, all_cleanup_queries)
219+
return fields

0 commit comments

Comments
 (0)