【问题标题】:"relation already exists" after adding a Many2many field in odoo在odoo中添加Many2many字段后“关系已经存在”
【发布时间】:2014-11-21 15:54:34
【问题描述】:

我定义了以下两个 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 属性时,问题仍然存在(当然错误消息中的关系名称会更改以反映重命名),所以它不像只是与一些已经存在的旧关系发生冲突在数据库中。

【问题讨论】:

    标签: python postgresql openerp relationship odoo


    【解决方案1】:

    我想通了。我不得不说,我认为这在技术上属于 Odoo 中的一个错误。

    总结

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

    详情

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

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

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

    但是有一个问题。默认情况下 PostgreSQL 中的标识符(包括索引标识符)can not be longer than 63 characters:

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

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

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

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

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

    【讨论】:

    • 我在 Odoo 的错误跟踪系统中创建了a ticket about the issue
    • 干得好!作为一种解决方法,您可以强制为关系名称添加一个名称,并将属性 relation='<forced_rel_table_name>' 添加到字段中。
    • 伟大的收获!我今天也遇到了这个问题,看来是这样。
    【解决方案2】:

    我认为您的代码没有任何问题。也许您遇到了 ORM 无法很好处理的极端情况,结果是或者尝试了关系的几种变体。

    可能尝试使用新初始化的数据库。

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

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

    【讨论】:

    • 不,不幸的是,即使创建一个新的数据库也不起作用。尝试在我刚刚创建的新数据库上安装模块时,我得到了完全相同的消息。
    • 好的,这是我自己想出来的,并在这里发布了我自己的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多