python - "relation already exists"在 odoo 中添加 Many2many 字段后

标签 python postgresql openerp relationship 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 属性时,问题仍然存在(当然,错误消息中的关系名称会更改以反射(reflect)重命名),所以这不仅仅是与冲突一些旧的关系已经存在于数据库中。

最佳答案

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

总结

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

详情

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

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

在哪里<model1><model2>_name适当模型的属性。您可以在 _m2m_raise_or_create_relation 中观察到这一点odoo的方法BaseModel .

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

The system uses no more than NAMEDATALEN-1 bytes of an identifier; longer names can be written in commands, but they will be truncated. By default, NAMEDATALEN is 64 so the maximum identifier length is 63 bytes.

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

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

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

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

关于python - "relation already exists"在 odoo 中添加 Many2many 字段后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26062915/

相关文章:

python - 管理包: PyCharm vs conda vs pip

python - 从 "_ElementUnicodeResult object of lxml.etree module"创建列表对象

sql - postgres 的数据文件夹的权限应该是什么

postgresql - 如何发现 Postgresql 表的用途是什么?

postgresql - 为什么 atttypmod 不同于 character_maximum_length?

openerp - Odoo 10 - 如何在 __manifest__ 中包含 Python 包依赖项

python - 生产中是否需要 Python 虚拟环境?

python - 将数据作为 RDD 保存回 Cassandra

用于选择最后一个内部标签的 Xpath 表达式

openerp - 如何在odoo中返回表单编辑 View ?