繁体   English   中英

在odoo中添加了Many2many字段后,“关系已经存在”

[英]“relation already exists” after adding a Many2many field in odoo

我已经定义了以下两个odoo ORM模型:

class Weekday(models.Model):
    _name = 'ludwik.offers.weekday'
    name = fields.Char()

class Duration(models.Model):
    _name = 'ludwik.offers.duration'
    weekday = fields.Many2many('ludwik.offers.weekday')

当我尝试启动odoo时,我收到以下消息:

ProgrammingError: relation "ludwik_offers_duration_ludwik_offers_weekday_rel_ludwik_offers_" already exists

此外,当我更改模型中的_name属性时,问题仍然存在(当然错误消息中的关系名称会更改以反映重命名),因此它不仅仅与数据库中已存在的某些旧关系发生冲突。

我想通了。 我不得不说,我认为这在技术上有资格作为Odoo中的错误。

摘要

我模特的名字太长了。 每次设置长度超过16个字符的_name属性时,您都可能会遇到此问题。

细节

创建Many2many关系时,odoo Many2many关系设置新的数据库表,然后为该表创建两个数据库索引。 他们的名字如下:

  • <model1>_<model2>_rel_<model1>_id_index
  • <model1>_<model2>_rel_<model2>_id_index

其中<model1><model2>是相应模型的_name属性。 您可以在_m2m_raise_or_create_relation的BaseModel的BaseModel方法中观察到这BaseModel

然而有一个问题。 默认情况下,PostgreSQL中的整数(包括索引标识符) 不能超过63个字符

系统使用的标识符不超过NAMEDATALEN-1个字节; 较长的名称可以用命令编写,但它们会被截断。 默认情况下,NAMEDATALEN为64,因此最大标识符长度为63个字节。

Odoo没有考虑到这一点。 它很乐意生成更长的标识符,然后被PostgreSQL截断。 如果两个标识符共享相同的前63个字符(很可能是较长的标识符),它们将被PostgreSQL视为相同。 这意味着将创建第一个索引,但创建第二个索引将导致错误,因为它共享已使用的标识符(至少根据PostgreSQL)。

那么_name属性在避免问题时可以拥有的最大长度是多少? 它取决于m2m关系中两个模型的名称之间共享的字符数,但为了完全避免标识符截断,您不应使用长度超过16个字符的名称。

为什么16? PostgreSQL标识符不能超过63个字符。 在odoo生成的索引标识符中,有15个固定字符。 这留下了48个字符,这些字符必须容纳三个重复的模型名称。 这反过来使每个模型名称留下16个字符。

解决该问题的另一种方法是通过Many2many字段上的relation属性手动设置短关系名称。

我的代码没有看到任何问题。 也许你到达角落的情况下,ORM无法很好地处理,结果或试验了几种关系的变化。

可能尝试使用刚刚初始化的数据库会起作用。

如果您真的想继续使用当前数据库,可以尝试卸载模块然后重新安装。 这应该删除它的数据库对象然后重新创建。

最后,它不起作用,尝试手动删除数据库中的ludwik_offers表并升级您的模块,以便重新创建它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM