Python &引用;“关系已存在”;在odoo中添加多个字段后
我定义了以下两个ODOORM模型:Python &引用;“关系已存在”;在odoo中添加多个字段后,python,postgresql,openerp,relationship,odoo,Python,Postgresql,Openerp,Relationship,Odoo,我定义了以下两个ODOORM模型: 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时,我收到以下
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
另外,当我在模型中更改
\u name
属性时,问题仍然存在(当然,错误消息中的关系名称会更改以反映重命名),因此这并不是因为它与数据库中已经存在的一些旧关系冲突。我看不出您的代码有任何问题。也许您遇到了ORM无法很好处理的一个极端情况,或者您尝试了关系的几种变化
可能尝试使用新初始化的数据库会起作用
如果您确实想继续使用当前数据库,可以尝试卸载模块,然后重新安装。应该删除它的数据库对象,然后重新创建
最后,如果不起作用,请尝试手动删除数据库中的
ludwik_提供的表,并升级您的模块,以便重新创建它们。我解决了这个问题。我不得不说,我认为这在技术上符合奥多的缺陷
摘要
我模特的名字太长了。每次将\u name
属性设置为长度超过16个字符时,您都可能会遇到此问题
详细信息
当您创建一个Many2many
关系时,odoo会为此关系设置一个新的数据库表,然后为该表创建两个数据库索引。他们的名字如下:
\uuuuu rel\uuuuu id\u索引
\uuuuu rel\uuuuu id\u索引
其中
和
是相应型号的\u name
属性。您可以在odoo的基本模型的方法中观察到这一点
然而,有一个陷阱。默认情况下,PostgreSQL中的索引器(包括索引标识符):
系统使用的标识符不超过NAMEDATALEN-1字节;
可以在命令中写入更长的名称,但它们将被截断。
默认情况下,NAMEDATALEN为64,因此最大标识符长度为63
字节
奥多没有考虑到这一点。它会生成更长的标识符,然后被PostgreSQL截断。如果两个标识符共享相同的前63个字符(对于较长的标识符,很可能是相同的),PostgreSQL会将它们视为相同的。这意味着将创建第一个索引,但创建第二个索引将导致错误,因为它共享已使用的标识符(至少根据PostgreSQL)
那么\u name
属性在避免问题时可以具有的最大长度是多少?这取决于m2m关系中两个模型的名称之间共享的字符数,但为了完全避免标识符截断,您不应使用长度超过16个字符的名称
为什么是16岁?PostgreSQL标识符不能超过63个字符。在odoo生成的索引标识符中有15个固定字符。这就给我们留下了48个字符,它们必须容纳三个重复的型号名称。这反过来给我们留下了每个型号名称16个字符
解决此问题的另一种方法是通过Many2many
字段上的relation
属性手动设置一个简短的关系名。否,不幸的是,即使创建新的数据库也无法工作。当我尝试在我刚刚创建的新数据库上安装模块时,我得到了同样的消息。好的,我自己解决了这个问题,并在这里发布了我自己的答案。我在Odoo的bug跟踪系统中创建的。做得很好!作为一种解决方法,您可以强制为关系名称添加一个名称,并在字段中添加一个atributerelation='
。太棒了!我今天也遇到了这个问题,看起来是这样。