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

Odoo Event模块注册触发utm_medium唯一约束冲突问题咨询

问题分析

为什么会触发唯一约束冲突?

  • UTM媒介模型的create方法通过utm.mixin的_get_unique_names做名称唯一性校验,但这个校验是大小写敏感的——它会把Email和email判定为两个不同的名称。
  • 但你的数据库对utm_medium.name字段采用了大小写不敏感的排序规则(比如PostgreSQL中使用大小写不敏感的collation),所以数据库层面会将Email和email视为同一个值,插入时触发唯一约束报错。

为什么Odoo没提前检查到?

因为Odoo代码里的校验逻辑是大小写敏感的,没把Email和email当成重复项,所以允许创建新记录,直到提交到数据库才被约束拦截。

修复方案

有两种实用的修复思路,按需选择:

思路一:让UTM名称校验大小写不敏感

在自定义模块里继承utm.medium,重写create方法,先检查是否存在大小写不同的同名记录,存在就直接复用,不创建新的:

from odoo import models, api

class UtmMedium(models.Model):
    _inherit = 'utm.medium'

    @api.model_create_multi
    def create(self, vals_list):
        for vals in vals_list:
            name = vals.get('name')
            if name:
                # 用=ilike做大小写不敏感匹配
                existing_medium = self.search([('name', '=ilike', name)], limit=1)
                if existing_medium:
                    # 把要创建的名称替换成已存在的名称,避免冲突
                    vals['name'] = existing_medium.name
        return super().create(vals_list)

思路二:强制统一UTM名称的大小写

如果希望所有UTM媒介名称格式统一(比如全小写),可以在创建时强制转换,同时更新现有记录:

1. 代码修改(自定义模块)

from odoo import models, api

class UtmMedium(models.Model):
    _inherit = 'utm.medium'

    @api.model_create_multi
    def create(self, vals_list):
        for vals in vals_list:
            if vals.get('name'):
                vals['name'] = vals['name'].lower()
        return super().create(vals_list)

2. 统一现有记录的大小写

备份数据库后,执行SQL语句更新现有记录:

UPDATE utm_medium SET name = lower(name);

紧急修复现有冲突

如果已经存在Email和email两条冲突记录,先清理:

  1. 备份数据库。
  2. 删除其中一条重复记录(比如保留Email):
DELETE FROM utm_medium WHERE name = 'email';
  1. 检查并更新所有关联了被删除记录的单据(销售订单、活动注册等),把utm_medium_id指向保留的记录。
注意事项
  • 不要直接修改Odoo核心模块代码,用自定义模块继承扩展,方便后续版本升级。
  • 这个问题通常是不同渠道生成的UTM名称大小写不一致导致的(比如邮件系统传Email,网站表单传email),统一格式能从根源避免问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 18:41:02