diff --git a/queue_job/migrations/10.0.1.0.0/end-migration.py b/queue_job/migrations/10.0.1.0.0/end-migration.py index 8e300fb518..74f2484456 100644 --- a/queue_job/migrations/10.0.1.0.0/end-migration.py +++ b/queue_job/migrations/10.0.1.0.0/end-migration.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Copyright 2017-2018 Tecnativa - Pedro M. Baeza # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) +import logging from odoo import api, SUPERUSER_ID @@ -12,6 +13,7 @@ def migrate(cr, version): if not version: return env = api.Environment(cr, SUPERUSER_ID, {}) + logger = logging.getLogger("odoo.addons.queue.migrations") QueueJob = env['queue.job'] groups = QueueJob.read_group( [], ['model_name', 'method_name'], ['model_name', 'method_name'], @@ -28,3 +30,23 @@ def migrate(cr, version): method.im_class._name, method.__name__, ), }) + # recompute func_string after other addons have adapted their + # args/kwargs/record_ids + records = env["queue.job"].search([]) + total = len(records) + count = 0 + error = 0 + for record in records: + count += 1 + if not count % 1000: + logger.info("Recomputing func_string of job %s of %s", + count, total) + try: + record._compute_func_string() + except KeyError: # unknown model or non-compliant arguments + error += 1 + logger.debug("Could not recompute func_string of queue.job#%s", + record.id) + + if error: + logger.warning("Could not recompute func_string of %s jobs", error) diff --git a/queue_job/migrations/10.0.1.0.0/post-migration.py b/queue_job/migrations/10.0.1.0.0/post-migration.py index d92848911e..30b906f6ef 100644 --- a/queue_job/migrations/10.0.1.0.0/post-migration.py +++ b/queue_job/migrations/10.0.1.0.0/post-migration.py @@ -1,6 +1,14 @@ # -*- coding: utf-8 -*- # Copyright 2018 Tecnativa - Pedro M. Baeza # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) +import json +import logging +from cPickle import Unpickler +from StringIO import StringIO +from odoo.addons.queue_job.fields import JobEncoder + + +_logger = logging.getLogger(__name__) def migrate(cr, version): @@ -15,3 +23,40 @@ def migrate(cr, version): UPDATE queue_job SET method_name = reverse(split_part(reverse(func_name), '.', 1))""" ) + migrate_args_kwargs(cr) + + +def migrate_args_kwargs(cr): + """Extract args and kwargs from v9 func column, which is the tuple + (func_name, args, kwargs) pickled in a binary string. Ignore done + jobs for performance reasons""" + cr.execute( + 'select id, func from queue_job' + ) + records = cr.fetchall() + total = len(records) + count = 0 + error = 0 + for _id, func in records: + count += 1 + if not count % 1000: + _logger.info("Parsing arguments of job %s of %s", + count, total) + try: + func_name, args, kwargs = Unpickler(StringIO(func)).load() + except Exception: + _logger.exception( + 'Failed to parse func column for queue_job#%s', _id, + ) + error += 1 + continue + cr.execute( + 'update queue_job set args=%s, kwargs=%s where id=%s', + ( + json.dumps(args, cls=JobEncoder), + json.dumps(kwargs, cls=JobEncoder), + _id, + ), + ) + if error: + _logger.warning("Could not parse arguments of %s jobs", error)