You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Odoo委托继承中删除partner_id字段遇外键冲突求助

问题:删除委托继承模型的Many2one字段时触发外键冲突

我定义了如下自定义模型:

class Customer(models.Model):
    _name = "my_module.customer"
    _inherits = {"res.partner": "partner_id"}
    partner_id = fields.Many2one(comodel_name="res.partner", ondelete="restrict", required=True)
    # more fields...

数据库中已存在该模型及关联的res.partner记录,且这些res.partner记录同时关联了门户用户(res.users)。

现在想要删除该自定义模型中的partner_id字段,但升级模块时出现如下外键违反错误:

psycopg2.errors.ForeignKeyViolation: update or delete on table "res_partner" violates foreign key constraint "res_users_partner_id_fkey" on table "res_users"

我理解该错误是因为res.partner记录仍被res.users引用,但不明白为何Odoo要尝试删除与my_module.customer关联的res.partner记录,而非仅解除关联并删除partner_id列?使用委托继承时Many2one字段的行为是否有差异?

请问如何在保留res.partner和res.users记录的前提下,成功删除my_module.customer中的partner_id字段?


原因分析与解决方案

原因分析

Odoo的**委托继承(_inherits)**有特殊逻辑:子模型和父模型是强绑定关系,当你删除作为继承关联的Many2one字段时,Odoo会默认尝试级联删除关联的父模型(res.partner)记录——这是因为委托继承的设计逻辑是子模型依赖父模型存在,解除继承绑定(删除关联字段)时,Odoo会认为父模型记录不再被需要,从而触发删除操作,而你的res.partner又被res.users引用,所以触发外键冲突。这是委托继承特有的行为,和普通Many2one字段的删除逻辑完全不同。

分步解决方案

要保留res.partner和res.users记录,必须分两步操作:

第一步:解除委托继承,保留partner_id字段

修改模型代码,移除_inherits配置,但暂时保留partner_id字段,把它当成普通Many2one字段处理:

class Customer(models.Model):
    _name = "my_module.customer"
    # 移除_inherits配置
    partner_id = fields.Many2one(comodel_name="res.partner", ondelete="restrict", required=True)
    # more fields...

升级模块,此时Odoo会解除委托继承的绑定关系,不会删除res.partner记录。

第二步:删除partner_id字段

确认第一步升级成功后,再修改代码删除partner_id字段:

class Customer(models.Model):
    _name = "my_module.customer"
    # 移除partner_id字段
    # more fields...

再次升级模块,此时Odoo只会删除my_module_customer表中的partner_id列,不会触发res.partner的删除操作,自然不会和res.users的外键约束冲突。

内容的提问来源于stack exchange,提问作者Seaworn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 23:21:02