1. Django2.0+和Oracle11
Traceback (most recent call last):
File "/Users/user/anaconda3/lib/python3.6/site-packages/django/db/migrations/recorder.py", line 55, in ensure_schema
editor.create_model(self.Migration)
File "/Users/user/anaconda3/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 298, in create_model
self.execute(sql, params or None)
File "/Users/user/anaconda3/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 117, in execute
cursor.execute(sql, params)
File "/Users/user/anaconda3/lib/python3.6/site-packages/django/db/backends/utils.py", line 100, in execute
return super().execute(sql, params)
File "/Users/user/anaconda3/lib/python3.6/site-packages/django/db/backends/utils.py", line 68, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/Users/user/anaconda3/lib/python3.6/site-packages/django/db/backends/utils.py", line 77, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/Users/user/anaconda3/lib/python3.6/site-packages/django/db/backends/utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
File "/Users/user/anaconda3/lib/python3.6/site-packages/django/db/utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/Users/user/anaconda3/lib/python3.6/site-packages/django/db/backends/utils.py", line 83, in _execute
return self.cursor.execute(sql)
File "/Users/user/anaconda3/lib/python3.6/site-packages/django/db/backends/oracle/base.py", line 500, in execute
return self.cursor.execute(query, self._param_generator(params))
django.db.utils.DatabaseError: ORA-02000: missing ALWAYS keyword
原因:
Django2.0+只支持Oracle 12.1+以后的版本, Django2.0创建Oracle表时使用'GENERATED BY DEFAULT ON NULL' ,这个是Oracle 12c的新特性。官方ReleaseNotes
解决方案:
- 升级Oracle到12.1+.
- 降级Django到1.11-.
- 如果既不能控制Oracle版本(比如对接其它系统,对方提供的是Oracle视图时),也不想降级Django,可以通过避免使用manage去管理Oracle数据库中的表,即在表定义中设置Meta属性
managed=False
2. Django1.11和Oracle 11、cx_Oracle 7
File "django/db/backends/oracle/operations.py", line 229, in fetch_returned_insert_id
return int(cursor._insert_id_var.getvalue())
TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'
参考链接1
参考链接2
解决方式:
需要降级cx_Oracle 7到cx_Oracle 6
3. Django1.11和Oracle 11、cx_Oracle 6.0
"AttributeError: 'cx_Oracle.Cursor' object has no attribute 'numbersAsStrings'"
解决方案:
注释代码:
lib\site-packages\django\db\backends\oracle\base.py
def __init__(self, connection):
self.cursor = connection.cursor()
# Necessary to retrieve decimal values without rounding error.
self.cursor.numbersAsStrings = True
self.cursor.outputtypehandler = self._output_type_handler
# Default arraysize of 1 is highly sub-optimal.
self.cursor.arraysize = 100
# https://github.com/django/django/commit/d52577b62b3138674807ac74251fab7faed48331
将上述代码中 self.cursor.numbersAsStrings = True注释即可
4. Django1.11和Oracle 11、cx_Oracle 6.0
TypeError: argument of type 'int' is not iterable
def _rowfactory(row, cursor):
# Cast numeric values as the appropriate Python type based upon the
# cursor description, and convert strings to unicode.
casted = []
for value, desc in zip(row, cursor.description):
if value is not None and desc[1] is Database.NUMBER:
precision = desc[4] or 0
scale = desc[5] or 0
if scale == -127:
if precision == 0:
# NUMBER column: decimal-precision floating point
# This will normally be an integer from a sequence,
# but it could be a decimal value.
if '.' in value:
value = decimal.Decimal(value)
else:
value = int(value)
else:
# FLOAT column: binary-precision floating point.
# This comes from FloatField columns.
value = float(value)
elif precision > 0:
# NUMBER(p,s) column: decimal-precision fixed point.
# This comes from IntField and DecimalField columns.
if scale == 0:
value = int(value)
else:
value = decimal.Decimal(value)
elif '.' in value:
# No type information. This normally comes from a
# mathematical expression in the SELECT list. Guess int
# or Decimal based on whether it has a decimal point.
value = decimal.Decimal(value)
else:
value = int(value)
elif desc[1] in (Database.STRING, Database.FIXED_CHAR,
Database.LONG_STRING):
value = to_unicode(value)
casted.append(value)
return tuple(casted)
问题发生在:
当value=0时
if '.' in value:
解决方案:
升级Django到1.11.15 解决问题(pip install Django==1.11.15)