我们在使用django时经常会出现一些问题,比如在执行makemigrations,migrate问题时,下面我们就一起来看下相对应的问题及解决方案。
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的新特性。
解决方案:
升级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’
解决方式:
需要降级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
File “E:\python\lib\site-packages\django\db\backends\oracle\base.py”,
line 497, in execute
return self.cursor.execute(query, self._param_generator(params)) django.db.utils.DatabaseError: ORA-00955: name is already used by an
existing object
解决方案:
在报错base.py, line 497 前打印出报错信息(print(query)),删除对应数据库对象即可。
在遇到问题的时候,我们可以多方面找原因,然后再通过原因进行分析寻找解决方法,我们在django 执行makemigrations,migrate问题经常这样操作。