You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

访问增改表单URL触发OperationalError:指定cursor不存在

排查Django 1.11中cursor does not exist OperationalError的思路

这个cursor "_django_curs_xxxxxx_xx" does not exist的错误在Django 1.11这类老版本搭配数据库后端时,经常和连接复用、查询时机有关。结合你说的shell操作正常但表单渲染时出错的场景,给你几个具体的排查方向:

  • 先修复视图里的冗余查询
    你视图里写了User.objects.get(username=request.user),但request.user本身就是已经认证过的User对象,完全没必要再查一次数据库!这个多余的查询不仅浪费资源,还可能在连接不稳定时触发异常。直接替换成request.user,先排除这个明显的问题。

  • 检查数据库连接的存活与复用配置
    因为shell是单次连接操作,而web服务器(比如uWSGI/Gunicorn)是多进程/线程复用数据库连接的,很可能数据库端主动回收了闲置连接,但Django的连接池还在复用失效的连接:

    • 查看数据库的wait_timeoutinteractive_timeout参数,如果超时时间设置得太短,会导致闲置连接被数据库断开。可以适当调大这两个值,或者把Django数据库配置里的CONN_MAX_AGE设为0(每次请求后关闭连接),避免复用过期连接。
    • 临时测试:在视图的数据库查询前手动重置连接,比如添加from django.db import connection; connection.close(),看是否能解决问题。如果有效,就说明是连接复用的问题。
  • 排查模板渲染时的隐性数据库查询
    你在视图里已经组装好了form,但模板渲染表单时,某些字段(比如ModelChoiceFieldChoiceField关联了模型查询集)可能会延迟触发数据库查询,这时候如果连接已经失效就会报错:

    • 检查EdfDataAssetFormatForm的字段定义,有没有那种没有提前求值的查询集。比如把表单里的queryset在视图里提前用list()强制求值,或者用select_related/prefetch_related预取关联数据,避免模板渲染时再发起查询。
    • 可以开启Django的DEBUG模式,查看请求的SQL日志,确认模板渲染时是否有额外的查询被触发。
  • 测试单线程服务器环境
    多进程/线程的服务器可能会导致连接池的冲突,你可以先用Django自带的runserver单线程模式启动(python manage.py runserver --noreload),如果问题消失,说明是服务器多进程/线程的连接管理问题。这时候需要调整服务器配置,比如让每个进程单独维护自己的数据库连接,或者限制连接复用的次数。

  • 检查数据库驱动与版本兼容性
    Django 1.11对新数据库版本的支持有限,比如如果你用的是MySQL 8.0,旧的MySQL-python驱动可能会有兼容性问题。尝试换成mysqlclient(Django推荐的驱动),并确保驱动版本和数据库版本匹配。同时查看数据库的错误日志,有没有关于连接断开的具体记录,这能帮你定位是数据库端还是客户端的问题。

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

火山引擎 最新活动