首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django错误ORA-01461解决方法?

Django错误ORA-01461解决方法?
EN

Stack Overflow用户
提问于 2014-01-18 06:56:58
回答 3查看 1.4K关注 0票数 2

我有一个Django (1.5版)应用程序,它收到以下Oracle错误:

代码语言:javascript
复制
ORA-01461: can bind a LONG value only for insert into a LONG column

在进行了一些数据库调试之后,问题似乎是由于使用SESSION_DATA (数据类型NCLOB)的较长(大约2.5k个字符) Unicode字符串值在DJANGO_SESSION表上执行INSERT而导致的。

我的一位同事告诉我,这个问题不会发生在更新上,而只发生在插入上,因为更新的Django数据库代码包含将数据库写入拆分成可管理的块的逻辑(我在这里解释),但由于某种原因,插入缺少该逻辑。

有了这些信息,我想我可以通过编写一小段自定义中间件来解决这个问题,该中间件使用SESSION_DATA的(可能)空值立即执行request.session.save(),然后在稍后设置会话数据时,这将导致更新而不是插入。

然而,事情似乎并没有那么简单。如果我在'django.contrib.sessions.middleware.SessionMiddleware',条目上方的settings.MIDDLEWARE_CLASSES中插入我的自定义中间件,request对象还没有session属性,并且我得到这个错误:

代码语言:javascript
复制
AttributeError: 'WSGIRequest' object has no attribute 'session'

如果我在SessionMiddleware条目之后插入我的中间件,那么在这个过程中就太晚了,我会得到原始的ORA-01461错误。

那么,有没有办法使用中间件来解决ORA-01461错误呢?还是一点都不想?

EN

回答 3

Stack Overflow用户

发布于 2014-06-13 19:43:01

检查这个Django bug:https://code.djangoproject.com/ticket/11487

我也解决了这个问题(在Django1.6上),并通过将4000字符检查更改为1000 here 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
EN

Stack Overflow用户

发布于 2015-08-27 05:24:09

对我起作用的变通方法是:

这应该是可行的:

代码语言:javascript
复制
class clob_unicode(unicode):
  def __new__(cls, *args, **kwargs):
    ret = unicode.__new__(cls, *args, **kwargs)
    import cx_Oracle 
    ret.input_size = cx_Oracle.CLOB # to set proper bind var type
    return ret

用法:

代码语言:javascript
复制
django_object.clob_variable = clob_unicode(u"some very long string")
django_object.save() # will use .input_size to set oracle bind var type

另请参阅this answer,以查看有关如何正确子类化和初始化string/Unicode子类对象(在__new__方法中初始化,而不是在__init__中初始化)的讨论。

票数 1
EN

Stack Overflow用户

发布于 2016-11-29 20:30:41

对我来说起作用的是在会话数据变得非常大之前创建并保存一个会话对象:

代码语言:javascript
复制
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作为更新命令而不是插入命令执行。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21197523

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档