我在 Django 中有以下模型:
class Event(models.Model):
# some fields
start_date = models.DateField()
end_date = models.DateField()
我在 Django 1.5 和 cx_oracle 5.1.2 中使用 Oracle 10g 数据库。这里的问题是当我尝试在管理界面中创建一个新对象(从日历中选择日期)时,会引发以下错误:
ORA-01843: not a valid month
syncdb
已创建 DATE
oracle 中的字段 start_date
和 end_date
.这看起来像后端错误还是我做错了什么?我确实有其他型号的
DateTimeField()
当我保留新对象时,它们工作正常,问题看起来与 DateField
有关。本身。更新:我检查了后端实现,在
backends/oracle/base.py
第 513 至 516 行:cursor.execute(
"ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'"
" NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'"
+ (" TIME_ZONE = 'UTC'" if settings.USE_TZ else ''))
执行此语句允许插入语句具有
DATE
的文字值。领域。我检查了后端生成的查询,它正在插入 '2013-03-20'
在 start_date
和 end_date
.日期匹配 NLS_DATE_FORMAT
,所以这在理论上应该有效!更新 : 我相信我的情况是 related to cx_oracle .
更新 :由于我仍然没有明确的答案(尽管我几乎可以肯定是 cx_oracle 导致了这个问题),我更改了我的
DateField
成DateTimeField
翻译成 oracle 的 TIMESTAMP
并且工作得很好。
最佳答案
基于 jtiai问题description ,我做了以下解决方法 - 在调用任何有问题的 sql-s(例如 oracle 10.5.0.2 和 11.2.0.1,cx_oracle 5.1.2)之前,再次重置 NLS_DATE_FORMAT/NLS_TIMESTAMP_FORMAT - 在 django/db/backends/oracle/base.py 中完成方法 def execute(...)
:
--- base.py 2013-10-31 12:19:24.000000000 +0100
+++ base_new.py 2013-10-31 12:20:32.000000000 +0100
@@ -707,6 +707,18 @@
query = convert_unicode(query % tuple(args), self.charset)
self._guess_input_sizes([params])
try:
+ # BUG-WORKAROUND: ulr1-131031
+ # https://stackoverflow.com/a/17269719/565525
+ # It's actually a bug in the Oracle 10.5.0.2 and 11.2.0.1. Bug can be reproduced as following:
+ # - set NLS_TIMESTAMP_FORMAT in session.
+ # - Run any implicit or explicit TO_DATE conversion with unicode data.
+ # - **Next implicit or explicit TO_TIMESTAMP with unicode data will trigger internal reset of timestamp format.**
+ # - All consecutive TO_TIMESTAMP will fail and TO_CHAR of timestamp will produce invalid output.
+ self.cursor.execute(
+ "ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'"
+ " NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'"
+ + (" TIME_ZONE = 'UTC'" if settings.USE_TZ else ''))
+
return self.cursor.execute(query, self._param_generator(params))
except Database.IntegrityError as e:
six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2])
关于Django - Oracle 后端错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15525312/