Skip to content

Commit

Permalink
[FIX] Preserve all translated fields on v16 migration
Browse files Browse the repository at this point in the history
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.

With this script, all translated fields will inherit their translations in all languages. Since it is executed in the `pre` phase of `base`, it should be able to still find the `ir_translation` table.

@moduon MT-7120
  • Loading branch information
yajo committed Aug 30, 2024
1 parent c8c1a6e commit 11feadb
Showing 1 changed file with 68 additions and 0 deletions.
68 changes: 68 additions & 0 deletions src/base/16.0.1/pre-translations2jsonb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""Store ir.translation records in jsonb fields."""

import logging

from psycopg2.errors import InvalidTableDefinition
from psycopg2.extras import Json
from psycopg2.sql import SQL, Identifier

from odoo.upgrade import util

_logger = logging.getLogger(__name__)


def migrate(cr, version):
already_converted = set()
missing_tables = set()
missing_columns = set()
cr.execute(
"""
SELECT name, res_id, src, jsonb_agg(lang) AS langs, jsonb_agg(value) AS values
FROM ir_translation
WHERE res_id != 0 AND type = 'model' AND state in ('translated', 'to_translate')
GROUP BY name, res_id, src
ORDER BY src IS NOT NULL
"""
)
for name, res_id, src, langs, values in cr.fetchall():
# Build a dict with all translations
all_values = dict(zip(langs, values), en_US=src)
if not all_values["en_US"]:
all_values["en_US"] = all_values[langs[0]]
# Find the translation target table and column
model, field = name.split(",")
table = util.table_of_model(cr, model)
# Skip early if the translation is no longer usable
if not util.table_exists(cr, table):
missing_tables.add(table)
continue
if not util.column_exists(cr, table, field):
missing_columns.add("{}.{}".format(table, field))
continue
# Make sure the field is translatable in JSONB format (noop if done already)
if (model, field) not in already_converted:
already_converted.add((model, field))
try:
util.convert_field_to_translatable(cr, model, field)
except InvalidTableDefinition:
_logger.debug("Couldn't convert %s.%s to jsonb", table, field, exc_info=True)
_logger.info("Skipping translation recovery for %s.%s", table, field)
# Store updated translation
cr.execute(
SQL("UPDATE {table} SET {field} = %s WHERE id = %s").format(
table=Identifier(table),
field=Identifier(field),
),
(Json(all_values), res_id),
)
# Log missing tables and columns
if missing_tables:
_logger.warning(
"Couldn't recover translation for these missing tables: %s",
", ".join(sorted(missing_tables)),
)
if missing_columns:
_logger.warning(
"Couldn't recover translation for these missing columns: %s",
", ".join(sorted(missing_columns)),
)

0 comments on commit 11feadb

Please sign in to comment.