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

Odoo创建ir.cron时报psycopg2.errors.NotNullViolation错误如何解决

报错根因

你遇到的非空约束报错直接原因是Odoo创建定时任务关联的服务动作(ir.actions.server)时,缺少必填的model_id字段值:

  • Odoo的ir.cron定时任务在state=code模式下,底层会自动生成一条关联的ir.actions.server记录,该表的model_id字段为非空必填项
  • 你编写的XML中只使用了model字段赋值,该字段是旧版本Odoo的废弃写法,无法正确给关联的服务动作传递模型ID值,因此插入数据库时触发非空约束报错。

除此之外,你的业务逻辑也存在设计问题:

  • 你定义的group_change方法要求传入vals参数,但定时任务调用时没有传参入口,执行时会触发参数不匹配报错
  • 用每分钟轮询的方式监听用户组变更效率极低,且无法实时捕获变更,存在漏日志的可能。
修复方案

方案1:保留定时任务逻辑的修复

如果一定要用定时任务实现,按如下修改:

  1. 修改XML定时任务定义,替换model字段为model_id,并把方法调用逻辑写在code字段中:
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
    <data noupdate="1">
        <record id="log_res_groups" model="ir.cron">
            <field name="name">Log User Changes</field>
            <field name="active" eval="True"/>
            <field name="user_id" ref="base.user_root"/>
            <field name="interval_number">1</field>
            <field name="interval_type">minutes</field>
            <field name="numbercall">-1</field>
            <field name="doall">1</field>
            <field name="state">code</field>
            <field name="model_id" ref="base.model_res_users"/>
            <field name="code">model.search([]).group_change()</field>
        </record>
    </data>
</odoo>
  1. 调整group_change方法逻辑,去掉不必要的vals参数和super调用,自行实现两次轮询的用户组差异对比逻辑即可。

方案2:更合理的事件触发方案(推荐)

直接重写res.users的write方法,用户组变更时实时触发日志记录,不需要定时任务,性能更高更准确:

from odoo import models
import logging

_logger = logging.getLogger(__name__)

class Users(models.Model):
    _inherit = 'res.users'

    def write(self, vals):
        if 'groups_id' not in vals:
            return super().write(vals)
        # 变更前统计用户组数量
        pre_group_count = len(self.groups_id)
        res = super().write(vals)
        # 变更后统计用户组数量
        post_group_count = len(self.groups_id)
        if pre_group_count > post_group_count:
            _logger.info("Admin user %s, removed %s from group", self.env.user.name, self.name)
        elif pre_group_count < post_group_count:
            _logger.info("Admin user %s, added %s to a group", self.env.user.name, self.name)
        return res

修改完成后直接删除原来的定时任务XML即可。

内容的提问来源于stack exchange,提问作者Justin Young

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 22:36:05