我有一个Django(版本1.5)应用程序正在收到此Oracle错误:
ORA-01461: can bind a LONG value only for insert into a LONG column
在进行一些数据库调试之后,似乎问题是由DJANGO_SESSION表上的INSERT执行的,该表具有SESSION_DATA(数据类型NCLOB)的长(大约2.5k字符)Unicode字符串值。
一位同事告诉我,问题不会发生在UPDATE上,而只会发生在INSERT上,因为UPDATEs的Django数据库代码包含逻辑(我在这里解释)将数据库写入分成可管理的块,但是某些原因导致INSERT缺少逻辑。
有了这些信息,我想我可以通过编写一小段自定义中间件来解决这个问题,该中间件立即执行request.session.save(),其中包含(可能)SESSION_DATA的空值,然后在会话时使用设置数据,这将导致UPDATE而不是INSERT。
然而,似乎并非如此简单。如果我在“django.contrib.sessions.middleware.SessionMiddleware”条目上方的settings.MIDDLEWARE_CLASSES中插入我的自定义中间件,请求对象还没有session属性,我收到此错误:
AttributeError: 'WSGIRequest' object has no attribute 'session'
如果我在SessionMiddleware条目之后插入我的中间件,那么在此过程中为时已晚,我得到原始的ORA-01461错误。
那么,有没有办法使用中间件解决ORA-01461错误?或者根本没有?
答案 0 :(得分:1)
检查这个Django错误:https://code.djangoproject.com/ticket/11487
我也遇到了这个问题(在Django 1.6上)并通过更改4000
字符检查来验证它1000
https://github.com/django/django/blob/stable/1.6.x/django/db/backends/oracle/base.py#L699。不幸的是,因为它是Django核心代码,所以在本地修复是一件困难的事情。
我没有测试过,但AFAICT问题至少已经尝试在Django 1.7中修复 - https://github.com/django/django/blob/stable/1.7.x/django/db/backends/oracle/base.py#L781
我想如果你不能升级到1.7(如果确实解决了这个问题),你可以找到会话数据增长太大的地方,并将其存储在其他地方 - 如果这是一个选项。
答案 1 :(得分:1)
对我来说有用的是在会话数据变得非常大之前创建和保存会话对象:
from django.contrib.sessions.backends.db import SessionStore
def view(request):
s = SessionStore()
s.create()
request.session = s
s.save()
# rest of the code here
后续查询作为更新命令执行,而不是作为oracle的插入执行。