Skip to content

Commit 182fe32

Browse files
committed
[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
1 parent c8c1a6e commit 182fe32

File tree

1 file changed

+81
-2
lines changed

1 file changed

+81
-2
lines changed

src/util/specific.py

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

4+
from psycopg2 import sql
5+
46
from .helpers import _validate_table
57
from .misc import _cached
68
from .models import rename_model
7-
from .modules import rename_module
8-
from .pg import column_exists, rename_table, table_exists
9+
from .modules import odoo, rename_module
10+
from .orm import env
11+
from .pg import column_exists, parallel_execute, rename_table, table_exists
912
from .report import add_to_migration_reports
1013

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

0 commit comments

Comments
 (0)