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




