为什么当我在 Odoo 10 中更新模块时,模块引入的数据记录被删除?

Why are data records introduced by a module removed when I update that module in Odoo 10?

我刚刚在Odoo 10 中恢复了一个数据库。我什至从服务器复制了实例的源代码和virtualenv 以保护环境。恢复正常,我可以使用数据库。

但是我想更新所有模块,在更新其中一些模块时出现严重错误。例如,当我尝试仅更新一个模块 (l10n_es) 时,出现此错误:

odoo.addons.base.ir.ir_model: Deleting 24@account.account.type (l10n_es.account_type_ingresos_neto) odoo.sql_db: bad query: DELETE FROM account_account_type WHERE id IN (24) ... NotNullViolation: null value in column "user_type_id" violates not-null constraint DETAIL: Failing row contains (712, null, other, Beneficios en activos financieros disponibles para la venta, 1, f, 1, 1, null, 900000000, 2018-02-01 09:28:54.453977, null, 2018-02-01 09:28:54.453977, null, f). CONTEXT: SQL statement "UPDATE ONLY "public"."account_account" SET "user_type_id" = NULL WHERE OPERATOR(pg_catalog.=) "user_type_id""

在进行更新之前,我进行了以下查询:

SELECT * FROM ir_model_data WHERE model='account.account.type' AND res_id=24;

其中returns以下:

  id  | create_uid |        create_date         |         write_date         | write_uid | noupdate |            name            |      date_init      |     date_update     | module  |        model         | res_id 
------+------------+----------------------------+----------------------------+-----------+----------+----------------------------+---------------------+---------------------+---------+----------------------+--------
 7850 |          1 | 2018-02-01 09:19:01.412377 | 2021-02-08 15:28:04.013464 |         1 | f        | account_type_ingresos_neto | 2018-02-01 09:19:01 | 2021-02-08 15:28:04 | l10n_es | account.account.type |     24

然后我执行这个:

SELECT * FROM account_account_type WHERE id=24;

哪个returns:

 id | create_uid |           name           | write_uid | note |         write_date         |        create_date         | include_initial_balance | type  
----+------------+--------------------------+-----------+------+----------------------------+----------------------------+-------------------------+-------
 24 |          1 | Ingresos patrimonio neto |         1 |      | 2021-02-08 15:28:04.013464 | 2018-02-01 09:19:01.412377 | t                       | other

通过这两个查询,我确认在数据库中有一个名为 Ingresos patrimonio neto 的 ID 为 24 的帐户类型,它具有 External XML ID l10n_es.account_type_ingresos_neto.

如果我检查实例代码,模块 l10n_es 有一个文件夹 data,其中有一个名为 account_type.xml 的文件。此文件由 __manifest__.py 调用并创建记录:

<record id="account_type_ingresos_neto" model="account.account.type">
    <field name="name">Ingresos patrimonio neto</field>
    <field name="include_initial_balance" eval="True"/>
</record>

所以,我不明白为什么当我更新模块时,它删除了这条记录(这个事实产生了错误):

odoo.addons.base.ir.ir_model: Deleting 24@account.account.type (l10n_es.account_type_ingresos_neto)

我认为当一个模块更新时,它删除了代码中不存在的外部XML ID(在数据库中)的记录(由它引入)不再,正如这个答案所解释的那样:

为什么当我更新它时,模块删除了仍然存在 XML ID 的现有记录?

确定的答案

最后我意识到我有罪模块 (l10n_es) 在 Odoo 实例中重复了两次。它位于 addons_path 参数调用的两个不同路径中。

对于版本 10.0 的 l10n_es,Odoo 社区协会在两个不同的存储库中拥有该模块:OCBl10n-spain。 Odoo 的更高版本不是这种情况,其中 OCA 使用 OCB l10n_es 并且不创建自己的 l10n_es.

旧答案

ir_model_data中更改模块或名称的问题(问题中引用的link的解决方案)是我们更改的那些记录可以在模块更新时重复。

我的解决方案是对冲突记录执行此查询:

UPDATE ir_model_data SET noupdate=TRUE WHERE module='l10n_es' AND name='account_type_ingresos_neto';

这样,更新模块时不会删除记录,因此其他记录(将它们设置为外键)不会引发非空错误。

事实上,我认为模块 l10n_es 应该在加载新记录的某些 XML 文件中将 <data> 标记更改为 <data noupdate="1">

但实际上,我不知道这是否是最好的解决方案。