Why is the account module upgrade unlinking records on some tables?

1.7k views Asked by At

I just wanted to make sure that upgrading the base or account module everything works fine, because if I pull new changes to the module I want to upgrade the database in a future.

I have created new records manually on the model account.acount.type. But when I try to upgrade the account module, the exception written at the bottom of this question is raised. Odoo is trying to remove records from that model. Why is this happening?

I have installed the account module, but I did not removed any record from that table, I've only added a few more types. So the expected behaviour of upgrading modules with data is:

noupdate means when second time this module will upgraded, this record will not be updated again. The record which is inside noupdate="1" will be initialized only at installation time.

Tip: In case if you delete the record then at next update system will Re-create it. Usually those kind of records which are having possibility of modification from front end, given inside noupdate=1. For example, automatic scheduler records.

<data noupdate="1">
    <!-- account.account.type -->
    <record model="account.account.type" id="data_account_type_receivable">
        <field name="name">Receivable</field>
        <field name="type">receivable</field>
        <field name="include_initial_balance" eval="True"/>
    </record>

    <!-- [...]  -->

This is the raised error on the log while upgrading the account module

2018-12-11 20:35:31,729 18018 INFO db_name odoo.addons.base.ir.ir_model: Deleting [email protected] (l10n_es.account_type_third_parties)
2018-12-11 20:35:31,760 18018 ERROR db_name odoo.sql_db: bad query: b'DELETE FROM account_account_type WHERE id IN (59)'
ERROR: null value in column "user_type_id" violates not-null constraint
DETAIL:  Failing row contains (14927, Account name or description, null, 4, f, null, other, null, f, null, 1, null, 1, 2018-12-11 18:10:24.091826, 1, 2018-12-11 18:10:24.091826, t).
CONTEXT:  SQL statement "UPDATE ONLY "public"."account_account" SET "user_type_id" = NULL WHERE $1 OPERATOR(pg_catalog.=) "user_type_id""
2018-12-11 20:35:31,763 18018 WARNING db_name odoo.modules.loading: Transient module states were reset
2018-12-11 20:35:31,763 18018 ERROR db_name odoo.modules.registry: Failed to load registry
Traceback (most recent call last):
  File "/path/to/odoo/src/modules/registry.py", line 85, in new
    odoo.modules.load_modules(registry._db, force_demo, status, update_module)
  File "/path/to/odoo/src/modules/loading.py", line 414, in load_modules
    env['ir.model.data']._process_end(processed_modules)
  File "/path/to/odoo/src/linked/base/ir/ir_model.py", line 1628, in _process_end
    record.unlink()
  File "/path/to/odoo/src/models.py", line 2935, in unlink
    cr.execute(query, (sub_ids,))
  File "/path/to/odoo/src/sql_db.py", line 155, in wrapper
    return f(self, *args, **kwargs)
  File "/path/to/odoo/src/sql_db.py", line 232, in execute
    res = self._obj.execute(query, params)
psycopg2.IntegrityError: null value in column "user_type_id" violates not-null constraint
This is raised because the account type is being used by some account.

Questions

  • So the only solution is to use the already existing account types instead of creating new ones?

  • Is there a place in the source code where this unlinking action is made? Does anyone know?

  • Is this the normal behaviour?

Note: I have imported the chart of accounts manually from scratch

1

There are 1 answers

2
CZoellner On BEST ANSWER

That should be normal behaviour especially for account.account.type which IIRC is no special model at all.

On module update odoo always deletes records for non existing external IDs. What are non existing external IDs in this context? They are external IDs in the system for example your l10n_es.account_type_third_parties which are not in the module anymore (here l10n_es).

Actually that is a very important information for odoo developers. I'm not sure if it's in the documentation.

And about the code: it's happening here

@api.model
def _process_end(self, modules):
    """ Clear records removed from updated module data.
    This method is called at the end of the module loading process.
    It is meant to removed records that are no longer present in the
    updated data. Such records are recognised as the one with an xml id
    and a module in ir_model_data and noupdate set to false, but not
    present in self.loads.
    """
    if not modules or tools.config.get('import_partial'):
        return True

    bad_imd_ids = []
    self = self.with_context({MODULE_UNINSTALL_FLAG: True})

    query = """ SELECT id, name, model, res_id, module FROM ir_model_data
                WHERE module IN %s AND res_id IS NOT NULL AND noupdate=%s ORDER BY id DESC
            """
    self._cr.execute(query, (tuple(modules), False))
    for (id, name, model, res_id, module) in self._cr.fetchall():
        if (module, name) not in self.loads:
            if model in self.env:
                _logger.info('Deleting %s@%s (%s.%s)', res_id, model, module, name)
                record = self.env[model].browse(res_id)
                if record.exists():
                    record.unlink()
                else:
                    bad_imd_ids.append(id)
    if bad_imd_ids:
        self.browse(bad_imd_ids).unlink()
    self.loads.clear()