Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IMP] merge_records: support Serialized and 'Jsonb' fields (adapt to Odoo v16) #331

Merged
merged 2 commits into from
Jun 16, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 37 additions & 2 deletions openupgradelib/openupgrade_merge_records.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ def _change_reference_refs_orm(
def _change_translations_orm(
env, model_name, record_ids, target_record_id, exclude_columns
):
if version_info[0] > 15:
return
if ("ir_translation", "res_id") in exclude_columns:
return
translation_obj = env["ir.translation"]
Expand Down Expand Up @@ -326,6 +328,8 @@ def _change_translations_orm(
def _change_translations_sql(
env, model_name, record_ids, target_record_id, exclude_columns
):
if version_info[0] > 15:
return
if ("ir_translation", "res_id") in exclude_columns:
return
logged_query(
Expand Down Expand Up @@ -403,6 +407,25 @@ def apply_operations_by_field_type(
elif operation == "merge":
_list = filter(lambda x: x, field_vals)
vals[column] = " | ".join(_list)
elif field_type in ("jsonb", "serialized"):
operation = operation or "first_not_null"
if operation == "first_not_null":
field_vals.reverse()
field_val = {}
for x in field_vals:
field_val |= x or {}
if field_val:
if method == "sql":
if field_type == "serialized":
import json

vals[column] = json.dumps(field_val)
elif field_type == "jsonb":
from psycopg2.extras import Json

vals[column] = Json(field_val)
else:
vals[column] = field_val
elif field_type in ("integer", "float", "monetary"):
if operation or field_type != "integer":
field_vals = [0 if not x else x for x in field_vals]
Expand Down Expand Up @@ -537,6 +560,12 @@ def _adjust_merged_values_orm(
- other value: content on target record is preserved
* Selection fields:
- any value: content on target record is preserved
* Serialized fields:
- 'first_not_null' (default): For each found key, put first not null value.
- other value: content on target record is preserved
* Translatable (in v16 or greater) fields as 'Jsonb' columns:
- 'first_not_null' (default): For each found key, put first not null value.
- other value: content on target record is preserved
"""
model = env[model_name]
fields = model._fields.values()
Expand Down Expand Up @@ -564,7 +593,7 @@ def _adjust_merged_values_orm(
target_record_id,
field_spec,
_list,
field.type,
field.type if not (version_info[0] > 15 and field.translate) else "jsonb",
field.name,
op,
"orm",
Expand Down Expand Up @@ -634,14 +663,20 @@ def _adjust_merged_values_sql(
lists = list(zip(*(env.cr.fetchall())))
new_vals = {}
vals = {}
for i, (column, _column_type, field_type) in enumerate(dict_column_type):
for i, (column, column_type, field_type) in enumerate(dict_column_type):
if (
field_spec.get("openupgrade_other_fields", "") == "preserve"
and column not in field_spec
):
continue
op = field_spec.get(column, False)
_list = list(lists[i])
if column_type == "jsonb":
field_type = column_type
if field_type == "serialized":
import json

_list = [x if isinstance(x, dict) else json.loads(x) for x in _list]
field_vals = apply_operations_by_field_type(
env,
model_name,
Expand Down