From 91f9bf2b64fb2a9bc6f0da3b38bd8c9b34770269 Mon Sep 17 00:00:00 2001 From: pedrambiria <pebr@odoo.com> Date: Tue, 10 Jan 2023 14:16:49 +0000 Subject: [PATCH] [FIX] google_calendar: avoiding return of recordset when using ormcache Before this commit: In some cases where some events won't sync to Odoo properly you got the "Unable to use a closed cursor." error. The problem is that `_from_google_ids` function returns a recordset, and the underlying cursor may be closed. Steps to reproduce the issue: 1. Create user_A and user_B in Odoo 2. Sync user_A and user_B with Google calendar 3. Create an event with user_B on the Google calendar 4. Run the "Google Calendar: synchronization" cron 5. Change the created event's owner to user_A on the Google calendar 6. Run the "Google Calendar: synchronization" cron => You will get this error on the log, and the event won't sync: ``` Traceback (most recent call last): File "/home/odoo/src/odoo/odoo/api.py", line 886, in get return field_cache[record._ids[0]] KeyError: 99 During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/odoo/src/odoo/odoo/fields.py", line 1061, in __get__ value = env.cache.get(record, self) File "/home/odoo/src/odoo/odoo/api.py", line 889, in get raise CacheMiss(record, field) odoo.exceptions.CacheMiss: 'calendar.event(99,).google_id' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/odoo/src/odoo/addons/google_calendar/models/res_users.py", line 91, in _sync_all_google_calendar user.with_user(user).sudo()._sync_google_calendar(google) File "/home/odoo/src/odoo/addons/google_calendar/models/res_users.py", line 70, in _sync_google_calendar synced_events = self.env['calendar.event']._sync_google2odoo(events - recurrences, default_reminders=default_reminders) File "/home/odoo/src/odoo/addons/google_calendar/models/google_sync.py", line 147, in _sync_google2odoo existing = google_events.exists(self.env) File "/home/odoo/src/odoo/addons/google_calendar/utils/google_event.py", line 180, in exists events.odoo_ids(env) File "/home/odoo/src/odoo/addons/google_calendar/utils/google_event.py", line 88, in odoo_ids found = self._load_odoo_ids_from_db(env, model) File "/home/odoo/src/odoo/addons/google_calendar/utils/google_event.py", line 111, in _load_odoo_ids_from_db mapping = {e.google_id: e.id for e in odoo_events} # {google_id: odoo_id} File "/home/odoo/src/odoo/addons/google_calendar/utils/google_event.py", line 111, in <dictcomp> mapping = {e.google_id: e.id for e in odoo_events} # {google_id: odoo_id} File "/home/odoo/src/odoo/odoo/fields.py", line 1087, in __get__ recs._fetch_field(self) File "/home/odoo/src/odoo/odoo/models.py", line 3276, in _fetch_field self._read(fnames) File "/home/odoo/src/odoo/addons/calendar/models/calendar_event.py", line 436, in _read super()._read(fields) File "/home/odoo/src/odoo/odoo/models.py", line 3343, in _read cr.execute(query_str, params + [sub_ids]) File "<decorator-gen-20>", line 2, in execute File "/home/odoo/src/odoo/odoo/sql_db.py", line 89, in check raise psycopg2.OperationalError('Unable to use a closed cursor.') ``` The solution is to use ormcache on a function that returns the ids of the events. opw-3098799 closes odoo/odoo#109557 Signed-off-by: Arnaud Joset <arj@odoo.com> --- addons/google_calendar/models/google_sync.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/addons/google_calendar/models/google_sync.py b/addons/google_calendar/models/google_sync.py index ad09d16c2d18..95e3c3637321 100644 --- a/addons/google_calendar/models/google_sync.py +++ b/addons/google_calendar/models/google_sync.py @@ -70,7 +70,7 @@ class GoogleSync(models.AbstractModel): def write(self, vals): google_service = GoogleCalendarService(self.env['google.service']) if 'google_id' in vals: - self._from_google_ids.clear_cache(self) + self._event_ids_from_google_ids.clear_cache(self) synced_fields = self._get_google_synced_fields() if 'need_sync' not in vals and vals.keys() & synced_fields: vals['need_sync'] = True @@ -85,7 +85,7 @@ class GoogleSync(models.AbstractModel): @api.model_create_multi def create(self, vals_list): if any(vals.get('google_id') for vals in vals_list): - self._from_google_ids.clear_cache(self) + self._event_ids_from_google_ids.clear_cache(self) records = super().create(vals_list) google_service = GoogleCalendarService(self.env['google.service']) @@ -111,12 +111,15 @@ class GoogleSync(models.AbstractModel): return True return super().unlink() - @api.model - @ormcache_context('google_ids', keys=('active_test',)) def _from_google_ids(self, google_ids): if not google_ids: return self.browse() - return self.search([('google_id', 'in', google_ids)]) + return self.browse(self._event_ids_from_google_ids(google_ids)) + + @api.model + @ormcache_context('google_ids', keys=('active_test',)) + def _event_ids_from_google_ids(self, google_ids): + return self.search([('google_id', 'in', google_ids)]).ids def _sync_odoo2google(self, google_service: GoogleCalendarService): if not self: -- GitLab