Django错误ORA-01461解决方法?

时间:2014-01-17 22:56:58

标签: python django oracle session

我有一个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错误?或者根本没有?

2 个答案:

答案 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的插入执行。