为什么帐户模块升级会取消链接某些表上的记录?

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

我只是想确保升级 baseaccount 模块一切正常,因为如果我对模块进行新更改,我想在未来升级数据库。

我已经在模型上手动创建了新记录 account.acount.type。但是当我尝试升级 account 模块时,引发了写在这个问题底部的异常。 Odoo 正在尝试从该模型中删除记录。为什么会这样?

我已经安装了帐户模块,但我没有从中删除任何记录table,我只是添加了一些类型。所以 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>

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

这是升级帐户模块时日志中出现的错误

2018-12-11 20:35:31,729 18018 INFO db_name odoo.addons.base.ir.ir_model: Deleting 59@account.account.type (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  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.

问题

注意:我从头开始手动导入会计科目表

这应该是正常行为,尤其是 account.account.type,IIRC 根本不是特殊模型。

在模块更新时,odoo 总是删除不存在的外部 ID 的记录。在这种情况下,什么是不存在的外部 ID?它们是系统中的外部 ID,例如您的 l10n_es.account_type_third_parties,它们不再存在于模块中(这里是 l10n_es)。

其实这对odoo开发者来说是一个非常重要的信息。我不确定它是否在文档中。

关于代码:它正在发生 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()