From 00d5f625f18898036e241c92b43cf756dd3c936f Mon Sep 17 00:00:00 2001 From: ??? Date: Wed, 1 Apr 2026 10:06:02 +0200 Subject: [PATCH 1/3] [FIX] connector_extension: fix conflict resolution during migration to 18.0 --- connector_extension/components/binder.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/connector_extension/components/binder.py b/connector_extension/components/binder.py index 72f41c9a5..b7426254c 100644 --- a/connector_extension/components/binder.py +++ b/connector_extension/components/binder.py @@ -280,7 +280,6 @@ def bind_import(self, external_data, values, sync_date, for_create=False): **self.id2dict(external_id, in_field=True), } ) - self.env.cr.commit() # pylint: disable=E8102 def _prepare_binding_export_values(self, relation, external_data): external_id = self.dict2id(external_data, in_field=False) @@ -478,8 +477,6 @@ def to_binding_from_internal_key(self, relation): :param relation: odoo object, not a binding and without binding :return: binding """ - export_mapper = self.component(usage="export.mapper") - mapper_external_data = export_mapper.map_record(relation) ext_alt_id = getattr(self, self._external_alt_field, None) if not ext_alt_id: id_values = {} @@ -487,6 +484,8 @@ def to_binding_from_internal_key(self, relation): if isinstance(ext_alt_id, str): ext_alt_id = [ext_alt_id] + export_mapper = self.component(usage="export.mapper") + mapper_external_data = export_mapper.map_record(relation) id_fields = mapper_external_data._mapper.get_target_fields( mapper_external_data, fields=ext_alt_id ) @@ -537,7 +536,7 @@ def to_binding_from_internal_key(self, relation): import_mapper_exists = False if not import_mapper_exists: binding = self.bind_export(record, relation) - binding[self._sync_date_field] = fields.Datetime.now() + # binding[self._sync_date_field] = fields.Datetime.now() if not binding: raise InvalidDataError( f"The binding with external id {external_id} " @@ -563,9 +562,9 @@ def get_external_dict_ids(self, relation, check_external_id=True): external_id = self.to_external(relation, wrap=False) if check_external_id: assert external_id, ( - f"Unexpected error on {relation._name}:" - "The backend id cannot be obtained." - "At this stage, the backend record should have " + f"Error on {relation._name}:" + "The external id cannot be obtained." + "At this stage, the external record should have " "been already linked via " "._export_dependencies. " ) From 181468a5f02caec3d91799f93c60952d643d99e1 Mon Sep 17 00:00:00 2001 From: ??? Date: Wed, 1 Apr 2026 11:16:28 +0200 Subject: [PATCH 2/3] [FIX] connector_extension: remove cr.commit() from bind_export In Odoo 18, queue_job forbids commits during job execution via _prevent_commit to avoid releasing the job lock prematurely. The cr.commit() in bind_export was an optimization for concurrent binding creation that is no longer compatible. The _retry_unique_violation context manager still handles race conditions via PostgreSQL's UNIQUE constraint without needing an explicit commit. --- connector_extension/components/binder.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/connector_extension/components/binder.py b/connector_extension/components/binder.py index b7426254c..027cb00a0 100644 --- a/connector_extension/components/binder.py +++ b/connector_extension/components/binder.py @@ -20,7 +20,6 @@ import psycopg2 -import odoo from odoo import _, fields, models from odoo.exceptions import ValidationError from odoo.osv import expression @@ -312,13 +311,6 @@ def bind_export(self, external_data, relation): with self._retry_unique_violation(): values = self._prepare_binding_export_values(relation, external_data) binding = self.model.with_context(connector_no_export=True).create(values) - # Eager commit to avoid having 2 jobs - # exporting at the same time. The constraint - # will pop if an other job already created - # the same binding. It will be caught and - # raise a RetryableJobError. - if not odoo.tools.config["test_enable"]: - self.env.cr.commit() # pylint: disable=E8102 return binding def _additional_external_binding_fields(self, external_data, relation): From c6b6c953fc1d78ec9506166ccfff30ab5286b2e9 Mon Sep 17 00:00:00 2001 From: ??? Date: Tue, 7 Apr 2026 17:32:49 +0200 Subject: [PATCH 3/3] [IMP] connector_extension: change strict parameter to False in dict zip function --- connector_extension/components/binder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connector_extension/components/binder.py b/connector_extension/components/binder.py index 027cb00a0..f3a04efb6 100644 --- a/connector_extension/components/binder.py +++ b/connector_extension/components/binder.py @@ -96,7 +96,7 @@ def id2dict(self, _id, in_field=True, alt_field=False): if not isinstance(_id, (tuple | list)): _id = [_id] fields = self.get_id_fields(in_field=in_field, alt_field=alt_field) - return dict(zip(fields, _id, strict=True)) + return dict(zip(fields, _id, strict=False)) else: return None