From 51de5eb0418a5b7954e4dfb3849e2b00ff110cdd Mon Sep 17 00:00:00 2001 From: Christopher Ormaza Date: Mon, 16 Jul 2018 22:57:05 +0000 Subject: [PATCH] [FIX] core: disable wait_callback during copy_from MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apparently some solutions (e.g. bitnami) deploy odoo using async workers, and not all pg/psycopg2 features are supported in that mode, notably COPY FROM (bulk-copying data from a stream to postgres). Work around this issue by disabling "async mode" as we do the copy (by resetting the wait callback) then re-enabling it. While this is not an officially supported run mode, it should Do No Harmâ„¢ for normal operations and could help users and clients. Of important note: while this fixes an error running in async mode, it will also prevent the worker from yielding while copy_from is executing. Hopefully that doesn't take too long (as the entire point of the copy_from is to be fast) but there you are. Fixes odoo/odoo#24145 closes odoo/odoo#43481 X-original-commit: c4583cf89c2b24085a2eeafea5ef76f474c5ff84 Signed-off-by: Xavier Morel (xmo) --- odoo/models.py | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/odoo/models.py b/odoo/models.py index 5f9fa87346f..2abf9c7343f 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -40,7 +40,7 @@ from operator import attrgetter, itemgetter import babel.dates import dateutil.relativedelta -import psycopg2 +import psycopg2, psycopg2.extensions from lxml import etree from lxml.builder import E from psycopg2.extensions import AsIs @@ -755,19 +755,27 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): for r in missing ) fields = ['module', 'model', 'name', 'res_id'] - cr.copy_from(io.StringIO( - u'\n'.join( - u"%s\t%s\t%s\t%d" % ( - modname, - record._name, - xids[record.id][1], - record.id, - ) - for record in missing - )), - table='ir_model_data', - columns=fields, - ) + + # disable eventual async callback / support for the extent of + # the COPY FROM, as these are apparently incompatible + callback = psycopg2.extensions.get_wait_callback() + psycopg2.extensions.set_wait_callback(None) + try: + cr.copy_from(io.StringIO( + u'\n'.join( + u"%s\t%s\t%s\t%d" % ( + modname, + record._name, + xids[record.id][1], + record.id, + ) + for record in missing + )), + table='ir_model_data', + columns=fields, + ) + finally: + psycopg2.extensions.set_wait_callback(callback) self.env['ir.model.data'].invalidate_cache(fnames=fields) return (