Skip to content

Commit

Permalink
[FIX] base: keep translations for null src while upgrade
Browse files Browse the repository at this point in the history
The method ``update_translatable_fields`` is inspired in the core
``_get_translation_upgrade_queries`` method, which had a bug that has
been recently addressed in odoo/odoo#168038

Let's use that core method with openupgradelib so we can be up to date
with any further bugfix.

TT49615
  • Loading branch information
chienandalu committed Jun 19, 2024
1 parent 2217dfd commit c90e727
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 70 deletions.
42 changes: 42 additions & 0 deletions openupgrade_scripts/scripts/base/16.0.1.3/end-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright 2024 Tecnativa - David Vidal
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openupgradelib import openupgrade, openupgrade_160

from odoo.tools import column_exists


def update_translatable_fields(env):
"""Update ir.translation records to jsonb column values. We need to do it at the
end as we'll already have all the models in the registry"""
# exclude fields from translation update
exclusions = [
# ir.actions.* inherits the name and help columns from ir.actions.actions
("ir.actions.act_window", "name"),
("ir.actions.act_window", "help"),
("ir.actions.act_url", "name"),
("ir.actions.act_url", "help"),
("ir.actions.server", "name"),
("ir.actions.server", "help"),
("ir.actions.client", "name"),
("ir.actions.client", "help"),
("ir.actions.report", "name"),
("ir.actions.report", "help"),
]
fields = env["ir.model.fields"].search_read(
[("translate", "=", True)], ["model", "name"]
)
fields_spec = [
(f["model"], f["name"])
for f in fields
if (
(f["model"], f["name"]) not in exclusions
and env.get(f["model"])
and column_exists(env.cr, env[f["model"]]._table, f["name"])
)
]
openupgrade_160.migrate_translations_to_jsonb(env, fields_spec)


@openupgrade.migrate()
def migrate(env, version):
update_translatable_fields(env)
65 changes: 0 additions & 65 deletions openupgrade_scripts/scripts/base/16.0.1.3/pre-migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,69 +52,6 @@ def login_or_registration_required_at_checkout(cr):
)


def update_translatable_fields(cr):
# exclude fields from translation update
exclusions = {
# ir.actions.* inherits the name and help columns from ir.actions.actions
"ir.actions.act_window": ["name", "help"],
"ir.actions.act_url": ["name", "help"],
"ir.actions.server": ["name", "help"],
"ir.actions.client": ["name", "help"],
"ir.actions.report": ["name", "help"],
}
cr.execute(
"SELECT f.name, m.model FROM ir_model_fields f "
"JOIN ir_model m ON f.model_id=m.id WHERE f.translate"
)
for field, model in cr.fetchall():
if field in exclusions.get(model, []):
continue
table = openupgrade.get_model2table(model)
if not openupgrade.table_exists(cr, table):
_logger.warning(
"Couldn't find table for model %s - not updating translations", model
)
continue
columns = tools.sql.table_columns(cr, table)
if field in columns:
if columns[field]["udt_name"] in ["varchar", "text"]:
tools.sql.convert_column_translatable(cr, table, field, "jsonb")
else:
_logger.warning(
"Couldn't find column for field %s - not updating translations", field
)
continue
# borrowed from odoo/tools/translate.py#_get_translation_upgrade_queries
translation_name = "%s,%s" % (model, field)
openupgrade.logged_query(
cr,
f"""
WITH t AS (
SELECT it.res_id as res_id, jsonb_object_agg(it.lang, it.value) AS value,
bool_or(imd.noupdate) AS noupdate
FROM ir_translation it
LEFT JOIN ir_model_data imd ON imd.model = %(model)s AND imd.res_id = it.res_id
WHERE it.type = 'model' AND it.name = %(name)s AND it.state = 'translated'
GROUP BY it.res_id
)
UPDATE {table} m
SET "{field}" = CASE WHEN t.noupdate IS FALSE THEN t.value || m."{field}"
ELSE m."{field}" || t.value END
FROM t
WHERE t.res_id = m.id
""",
{
"model": model,
"name": translation_name,
},
)
openupgrade.logged_query(
cr,
"DELETE FROM ir_translation WHERE type = 'model' AND name = %s",
[translation_name],
)


@openupgrade.migrate(use_env=False)
def migrate(cr, version):
"""
Expand All @@ -139,5 +76,3 @@ def migrate(cr, version):
"USING ir_ui_view v "
"WHERE r.view_id=v.id AND v.inherit_id IS NOT NULL AND v.mode != 'primary'"
)
# update all translatable fields
update_translatable_fields(cr)
13 changes: 9 additions & 4 deletions openupgrade_scripts/scripts/utm/16.0.1.1/pre-migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@

@openupgrade.migrate()
def migrate(env, version):

# pre-migration of module base converted name column from utm_campaign
# into jsonb, hence it suffices to copy the name column into title.
openupgrade.copy_columns(env.cr, {"utm_campaign": [("name", "title", "jsonb")]})
# Name is now not translatable, while the new `title` field is and should have the
# former values of name. Let's copy those values and prepare for the tranlations
# migration to jsnob
openupgrade.copy_columns(env.cr, {"utm_campaign": [("name", "title", "varchar")]})
openupgrade.logged_query(
env.cr,
"""UPDATE ir_translation SET name = 'utm.campaign,title'
WHERE name = 'utm.campaign,name' AND type = 'model'""",
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ new model utm.source.mixin [abstract]

---Fields in module 'utm'---
utm / utm.campaign / title (char) : NEW required
# Done: populate title column with translation values of field name
# Done: copy column values from name. Translations will be get en migration-end

---XML records in module 'utm'---
NEW ir.model.access: utm.access_utm_medium_system
Expand Down

0 comments on commit c90e727

Please sign in to comment.