Fixed #27649 -- Bumped required cx_Oracle to 5.2.
Removed obsolete workarounds from1aa4889808
anddcf3be7a62
.
This commit is contained in:
parent
5eff8a7783
commit
fae56427e1
|
@ -62,7 +62,7 @@ from .features import DatabaseFeatures # NOQA isort:skip
|
|||
from .introspection import DatabaseIntrospection # NOQA isort:skip
|
||||
from .operations import DatabaseOperations # NOQA isort:skip
|
||||
from .schema import DatabaseSchemaEditor # NOQA isort:skip
|
||||
from .utils import Oracle_datetime, convert_unicode # NOQA isort:skip
|
||||
from .utils import Oracle_datetime # NOQA isort:skip
|
||||
|
||||
|
||||
class _UninitializedOperatorsDescriptor(object):
|
||||
|
@ -208,8 +208,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
|||
return conn_params
|
||||
|
||||
def get_new_connection(self, conn_params):
|
||||
conn_string = convert_unicode(self._connect_string())
|
||||
return Database.connect(conn_string, **conn_params)
|
||||
return Database.connect(self._connect_string(), **conn_params)
|
||||
|
||||
def init_connection_state(self):
|
||||
cursor = self.create_cursor()
|
||||
|
@ -246,13 +245,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
|||
self.operators = self._standard_operators
|
||||
self.pattern_ops = self._standard_pattern_ops
|
||||
cursor.close()
|
||||
|
||||
try:
|
||||
self.connection.stmtcachesize = 20
|
||||
except AttributeError:
|
||||
# Django docs specify cx_Oracle version 4.3.1 or higher, but
|
||||
# stmtcachesize is available only in 4.3.2 and up.
|
||||
pass
|
||||
self.connection.stmtcachesize = 20
|
||||
# Ensure all changes are preserved even when AUTOCOMMIT is False.
|
||||
if not self.get_autocommit():
|
||||
self.commit()
|
||||
|
@ -265,7 +258,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
|||
try:
|
||||
return self.connection.commit()
|
||||
except Database.DatabaseError as e:
|
||||
# cx_Oracle 5.0.4 raises a cx_Oracle.DatabaseError exception
|
||||
# cx_Oracle raises a cx_Oracle.DatabaseError exception
|
||||
# with the following attributes and values:
|
||||
# code = 2091
|
||||
# message = 'ORA-02091: transaction rolled back
|
||||
|
@ -363,7 +356,7 @@ class OracleParam(object):
|
|||
else:
|
||||
# To transmit to the database, we need Unicode if supported
|
||||
# To get size right, we must consider bytes.
|
||||
self.force_bytes = convert_unicode(param, cursor.charset, strings_only)
|
||||
self.force_bytes = force_text(param, cursor.charset, strings_only)
|
||||
if isinstance(self.force_bytes, six.string_types):
|
||||
# We could optimize by only converting up to 4000 bytes here
|
||||
string_size = len(force_bytes(param, cursor.charset, strings_only))
|
||||
|
@ -459,11 +452,11 @@ class FormatStylePlaceholderCursor(object):
|
|||
query = query[:-1]
|
||||
if params is None:
|
||||
params = []
|
||||
query = convert_unicode(query, self.charset)
|
||||
query = query
|
||||
elif hasattr(params, 'keys'):
|
||||
# Handle params as dict
|
||||
args = {k: ":%s" % k for k in params.keys()}
|
||||
query = convert_unicode(query % args, self.charset)
|
||||
query = query % args
|
||||
elif unify_by_values and len(params) > 0:
|
||||
# Handle params as a dict with unified query parameters by their
|
||||
# values. It can be used only in single query execute() because
|
||||
|
@ -480,23 +473,17 @@ class FormatStylePlaceholderCursor(object):
|
|||
params_dict = {param: ':arg%d' % i for i, param in enumerate(set(params))}
|
||||
args = [params_dict[param] for param in params]
|
||||
params = dict(zip(params_dict.values(), list(zip(*params_dict.keys()))[0]))
|
||||
query = convert_unicode(query % tuple(args), self.charset)
|
||||
query = query % tuple(args)
|
||||
else:
|
||||
# Handle params as sequence
|
||||
args = [(':arg%d' % i) for i in range(len(params))]
|
||||
query = convert_unicode(query % tuple(args), self.charset)
|
||||
return query, self._format_params(params)
|
||||
query = query % tuple(args)
|
||||
return force_text(query, self.charset), self._format_params(params)
|
||||
|
||||
def execute(self, query, params=None):
|
||||
query, params = self._fix_for_params(query, params, unify_by_values=True)
|
||||
self._guess_input_sizes([params])
|
||||
try:
|
||||
return self.cursor.execute(query, self._param_generator(params))
|
||||
except Database.DatabaseError as e:
|
||||
# cx_Oracle <= 4.4.0 wrongly raises a DatabaseError for ORA-01400.
|
||||
if hasattr(e.args[0], 'code') and e.args[0].code == 1400 and not isinstance(e, Database.IntegrityError):
|
||||
six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2])
|
||||
raise
|
||||
return self.cursor.execute(query, self._param_generator(params))
|
||||
|
||||
def executemany(self, query, params=None):
|
||||
if not params:
|
||||
|
@ -509,13 +496,7 @@ class FormatStylePlaceholderCursor(object):
|
|||
# more than once, we can't make it lazy by using a generator
|
||||
formatted = [firstparams] + [self._format_params(p) for p in params_iter]
|
||||
self._guess_input_sizes(formatted)
|
||||
try:
|
||||
return self.cursor.executemany(query, [self._param_generator(p) for p in formatted])
|
||||
except Database.DatabaseError as e:
|
||||
# cx_Oracle <= 4.4.0 wrongly raises a DatabaseError for ORA-01400.
|
||||
if hasattr(e.args[0], 'code') and e.args[0].code == 1400 and not isinstance(e, Database.IntegrityError):
|
||||
six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2])
|
||||
raise
|
||||
return self.cursor.executemany(query, [self._param_generator(p) for p in formatted])
|
||||
|
||||
def fetchone(self):
|
||||
row = self.cursor.fetchone()
|
||||
|
|
|
@ -11,7 +11,7 @@ from django.utils import six, timezone
|
|||
from django.utils.encoding import force_bytes, force_text
|
||||
|
||||
from .base import Database
|
||||
from .utils import InsertIdVar, Oracle_datetime, convert_unicode
|
||||
from .utils import InsertIdVar, Oracle_datetime
|
||||
|
||||
|
||||
class DatabaseOperations(BaseDatabaseOperations):
|
||||
|
@ -310,10 +310,10 @@ WHEN (new.%(col_name)s IS NULL)
|
|||
return "RETURNING %s INTO %%s", (InsertIdVar(),)
|
||||
|
||||
def savepoint_create_sql(self, sid):
|
||||
return convert_unicode("SAVEPOINT " + self.quote_name(sid))
|
||||
return "SAVEPOINT " + self.quote_name(sid)
|
||||
|
||||
def savepoint_rollback_sql(self, sid):
|
||||
return convert_unicode("ROLLBACK TO SAVEPOINT " + self.quote_name(sid))
|
||||
return "ROLLBACK TO SAVEPOINT " + self.quote_name(sid)
|
||||
|
||||
def sql_flush(self, style, tables, sequences, allow_cascade=False):
|
||||
# Return a list of 'TRUNCATE x;', 'TRUNCATE y;',
|
||||
|
|
|
@ -1,18 +1,7 @@
|
|||
import datetime
|
||||
|
||||
from django.utils.encoding import force_bytes, force_text
|
||||
|
||||
from .base import Database
|
||||
|
||||
# Check whether cx_Oracle was compiled with the WITH_UNICODE option if cx_Oracle is pre-5.1. This will
|
||||
# also be True for cx_Oracle 5.1 and in Python 3.0. See #19606
|
||||
if int(Database.version.split('.', 1)[0]) >= 5 and \
|
||||
(int(Database.version.split('.', 2)[1]) >= 1 or
|
||||
not hasattr(Database, 'UNICODE')):
|
||||
convert_unicode = force_text
|
||||
else:
|
||||
convert_unicode = force_bytes
|
||||
|
||||
|
||||
class InsertIdVar(object):
|
||||
"""
|
||||
|
|
|
@ -731,17 +731,7 @@ Oracle notes
|
|||
============
|
||||
|
||||
Django supports `Oracle Database Server`_ versions 11.2 and higher. Version
|
||||
4.3.1 or higher of the `cx_Oracle`_ Python driver is required, although we
|
||||
recommend version 5.1.3 or later as these versions support Python 3.
|
||||
|
||||
Note that due to a Unicode-corruption bug in ``cx_Oracle`` 5.0, that
|
||||
version of the driver should **not** be used with Django;
|
||||
``cx_Oracle`` 5.0.1 resolved this issue, so if you'd like to use a
|
||||
more recent ``cx_Oracle``, use version 5.0.1.
|
||||
|
||||
``cx_Oracle`` 5.0.1 or greater can optionally be compiled with the
|
||||
``WITH_UNICODE`` environment variable. This is recommended but not
|
||||
required.
|
||||
5.2 or higher of the `cx_Oracle`_ Python driver is required.
|
||||
|
||||
.. _`Oracle Database Server`: http://www.oracle.com/
|
||||
.. _`cx_Oracle`: http://cx-oracle.sourceforge.net/
|
||||
|
|
|
@ -698,6 +698,8 @@ Miscellaneous
|
|||
leaves ``request.POST`` immutable. If you're modifying that ``QueryDict``,
|
||||
you must now first copy it, e.g. ``request.POST.copy()``.
|
||||
|
||||
* Support for ``cx_Oracle`` < 5.2 is removed.
|
||||
|
||||
.. _deprecated-features-1.11:
|
||||
|
||||
Features deprecated in 1.11
|
||||
|
|
|
@ -86,11 +86,8 @@ class OracleTests(unittest.TestCase):
|
|||
def test_dbms_session(self):
|
||||
# If the backend is Oracle, test that we can call a standard
|
||||
# stored procedure through our cursor wrapper.
|
||||
from django.db.backends.oracle.base import convert_unicode
|
||||
|
||||
with connection.cursor() as cursor:
|
||||
cursor.callproc(convert_unicode('DBMS_SESSION.SET_IDENTIFIER'),
|
||||
[convert_unicode('_django_testing!')])
|
||||
cursor.callproc('DBMS_SESSION.SET_IDENTIFIER', ['_django_testing!'])
|
||||
|
||||
def test_cursor_var(self):
|
||||
# If the backend is Oracle, test that we can pass cursor variables
|
||||
|
|
Loading…
Reference in New Issue