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

Django使用ORM执行obj.save()报set_session相关ProgrammingError如何解决

报错根因

django.db.utils.ProgrammingError: set_session cannot be used inside a transaction 错误本质是PostgreSQL的运行限制:不允许在已开启的事务中执行set_session修改会话级参数,结合Django ORM的执行逻辑,通常触发场景如下:

  • Django的obj.save()默认会在事务中执行写入操作,如果你在事务开启后(包括ATOMIC_REQUESTS开启的全局请求事务、手动用atomic()装饰器/上下文开启的事务),调用了修改数据库会话参数的逻辑(比如修改会话时区、编码、只读属性等),就会触发该报错
  • 自定义的信号处理器、中间件中存在修改数据库会话的逻辑,且这部分逻辑会在事务开启后执行
  • 用到的第三方Django包(比如多租户类库django-tenants)内部存在事务内调用set_session的兼容性问题
  • psycopg2/psycopg3数据库适配器和当前Django、PostgreSQL版本不兼容
解决方案
  • 调整会话参数修改时机

    定位所有调用connection.set_session()或者原生SET语句修改会话参数的代码,将这部分逻辑移到事务开启前执行,也可以增加事务状态判断避免异常:
    from django.db import connection
    
    # 仅在非事务状态下修改会话参数
    if not connection.in_atomic_block:
        connection.set_session(
            autocommit=True,
            timezone='UTC'
        )
    
  • 调整事务配置

    如果对应业务不需要强制开启事务,可以给相关视图添加@transaction.non_atomic_requests装饰器,关闭该视图的全局请求事务,避免事务自动开启后触发会话修改限制
  • 修复第三方包兼容问题

    检查是否使用了会修改数据库会话的第三方包,优先升级到对应包的最新稳定版,这类兼容性问题通常会在官方后续版本修复;如果无法升级,可以自行重写包内调用set_session的逻辑,补充事务状态判断
  • 适配数据库适配器版本

    部分版本的psycopg2/psycopg3存在事务内会话修改的处理缺陷,可以根据你当前的Django版本切换适配的适配器版本,比如Django 4.2+可适配psycopg 3.1+、Django 3.2可适配psycopg2-binary 2.9.x版本

内容的提问来源于stack exchange,提问作者Krishna Manohar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 15:45:07