Skip to content

Commit ae05ea4

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 ae05ea4

File tree

1 file changed

+76
-1
lines changed

1 file changed

+76
-1
lines changed

src/util/specific.py

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
from .helpers import _validate_table
55
from .misc import _cached
66
from .models import rename_model
7-
from .modules import rename_module
7+
from .modules import odoo, rename_module
8+
from .orm import env
89
from .pg import column_exists, rename_table, table_exists
910
from .report import add_to_migration_reports
1011

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

0 commit comments

Comments
 (0)