mirror of
https://github.com/django/django.git
synced 2025-01-18 14:24:39 +00:00
Refs #33817 -- Removed support for cx_Oracle per deprecation timeline.
This commit is contained in:
parent
0a0f9b4acc
commit
b4bc393b23
@ -1,6 +1,7 @@
|
||||
import oracledb
|
||||
|
||||
from django.contrib.gis.db.backends.base.adapter import WKTAdapter
|
||||
from django.contrib.gis.geos import GeometryCollection, Polygon
|
||||
from django.db.backends.oracle.oracledb_any import oracledb
|
||||
|
||||
|
||||
class OracleSpatialAdapter(WKTAdapter):
|
||||
|
@ -1,5 +1,6 @@
|
||||
import oracledb
|
||||
|
||||
from django.db.backends.oracle.introspection import DatabaseIntrospection
|
||||
from django.db.backends.oracle.oracledb_any import oracledb
|
||||
from django.utils.functional import cached_property
|
||||
|
||||
|
||||
|
@ -14,7 +14,6 @@ from django.conf import settings
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.db import IntegrityError
|
||||
from django.db.backends.base.base import BaseDatabaseWrapper
|
||||
from django.db.backends.oracle.oracledb_any import is_oracledb
|
||||
from django.db.backends.utils import debug_transaction
|
||||
from django.utils.asyncio import async_unsafe
|
||||
from django.utils.encoding import force_bytes, force_str
|
||||
@ -22,7 +21,7 @@ from django.utils.functional import cached_property
|
||||
from django.utils.version import get_version_tuple
|
||||
|
||||
try:
|
||||
from django.db.backends.oracle.oracledb_any import oracledb as Database
|
||||
import oracledb as Database
|
||||
except ImportError as e:
|
||||
raise ImproperlyConfigured(f"Error loading oracledb module: {e}")
|
||||
|
||||
@ -286,11 +285,6 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||
return self.oracle_version
|
||||
|
||||
def get_connection_params(self):
|
||||
# Pooling feature is only supported for oracledb.
|
||||
if self.is_pool and not is_oracledb:
|
||||
raise ImproperlyConfigured(
|
||||
"Pooling isn't supported by cx_Oracle. Use python-oracledb instead."
|
||||
)
|
||||
conn_params = self.settings_dict["OPTIONS"].copy()
|
||||
if "use_returning_into" in conn_params:
|
||||
del conn_params["use_returning_into"]
|
||||
|
@ -1,6 +1,5 @@
|
||||
from django.db import DatabaseError, InterfaceError
|
||||
from django.db.backends.base.features import BaseDatabaseFeatures
|
||||
from django.db.backends.oracle.oracledb_any import is_oracledb
|
||||
from django.utils.functional import cached_property
|
||||
|
||||
|
||||
@ -158,16 +157,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
||||
},
|
||||
}
|
||||
)
|
||||
if is_oracledb and self.connection.oracledb_version >= (2, 1, 2):
|
||||
skips.update(
|
||||
{
|
||||
"python-oracledb 2.1.2+ no longer hides 'ORA-1403: no data found' "
|
||||
"exceptions raised in database triggers.": {
|
||||
"backends.oracle.tests.TransactionalTests."
|
||||
"test_hidden_no_data_found_exception"
|
||||
},
|
||||
},
|
||||
)
|
||||
return skips
|
||||
|
||||
@cached_property
|
||||
|
@ -1,10 +1,11 @@
|
||||
from collections import namedtuple
|
||||
|
||||
import oracledb
|
||||
|
||||
from django.db import models
|
||||
from django.db.backends.base.introspection import BaseDatabaseIntrospection
|
||||
from django.db.backends.base.introspection import FieldInfo as BaseFieldInfo
|
||||
from django.db.backends.base.introspection import TableInfo as BaseTableInfo
|
||||
from django.db.backends.oracle.oracledb_any import oracledb
|
||||
|
||||
FieldInfo = namedtuple(
|
||||
"FieldInfo", BaseFieldInfo._fields + ("is_autofield", "is_json", "comment")
|
||||
|
@ -3,7 +3,7 @@ import uuid
|
||||
from functools import lru_cache
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import DatabaseError, NotSupportedError
|
||||
from django.db import NotSupportedError
|
||||
from django.db.backends.base.operations import BaseDatabaseOperations
|
||||
from django.db.backends.utils import split_tzname_delta, strip_quotes, truncate_name
|
||||
from django.db.models import AutoField, Exists, ExpressionWrapper, Lookup
|
||||
@ -295,15 +295,6 @@ END;
|
||||
columns = []
|
||||
for param in returning_params:
|
||||
value = param.get_value()
|
||||
# Can be removed when cx_Oracle is no longer supported and
|
||||
# python-oracle 2.1.2 becomes the minimum supported version.
|
||||
if value == []:
|
||||
raise DatabaseError(
|
||||
"The database did not return a new row id. Probably "
|
||||
'"ORA-1403: no data found" was raised internally but was '
|
||||
"hidden by the Oracle OCI library (see "
|
||||
"https://code.djangoproject.com/ticket/28859)."
|
||||
)
|
||||
columns.append(value[0])
|
||||
return tuple(columns)
|
||||
|
||||
|
@ -1,20 +0,0 @@
|
||||
import warnings
|
||||
|
||||
from django.utils.deprecation import RemovedInDjango60Warning
|
||||
|
||||
try:
|
||||
import oracledb
|
||||
|
||||
is_oracledb = True
|
||||
except ImportError as e:
|
||||
try:
|
||||
import cx_Oracle as oracledb # NOQA
|
||||
|
||||
warnings.warn(
|
||||
"cx_Oracle is deprecated. Use oracledb instead.",
|
||||
RemovedInDjango60Warning,
|
||||
stacklevel=2,
|
||||
)
|
||||
is_oracledb = False
|
||||
except ImportError:
|
||||
raise e from None
|
@ -990,10 +990,6 @@ Oracle notes
|
||||
Django supports `Oracle Database Server`_ versions 19c and higher. Version
|
||||
2.3.0 or higher of the `oracledb`_ Python driver is required.
|
||||
|
||||
.. deprecated:: 5.0
|
||||
|
||||
Support for ``cx_Oracle`` is deprecated.
|
||||
|
||||
.. _`Oracle Database Server`: https://www.oracle.com/
|
||||
.. _`oracledb`: https://oracle.github.io/python-oracledb/
|
||||
|
||||
|
@ -281,6 +281,8 @@ to remove usage of these features.
|
||||
|
||||
* The ``ForeignObject.get_reverse_joining_columns()`` method is be removed.
|
||||
|
||||
* Support for ``cx_Oracle`` is removed.
|
||||
|
||||
See :ref:`deprecated-features-5.1` for details on these changes, including how
|
||||
to remove usage of these features.
|
||||
|
||||
|
@ -3,16 +3,11 @@ import unittest
|
||||
from unittest import mock
|
||||
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.db import DatabaseError, NotSupportedError, ProgrammingError, connection
|
||||
from django.db import NotSupportedError, ProgrammingError, connection
|
||||
from django.db.models import BooleanField
|
||||
from django.test import TestCase, TransactionTestCase
|
||||
|
||||
from ..models import Square, VeryLongModelNameZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
|
||||
|
||||
try:
|
||||
from django.db.backends.oracle.oracledb_any import is_oracledb
|
||||
except ImportError:
|
||||
is_oracledb = False
|
||||
from ..models import VeryLongModelNameZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
|
||||
|
||||
|
||||
def no_pool_connection(alias=None):
|
||||
@ -85,7 +80,6 @@ class Tests(TestCase):
|
||||
connection.check_database_version_supported()
|
||||
self.assertTrue(mocked_get_database_version.called)
|
||||
|
||||
@unittest.skipUnless(is_oracledb, "Pool specific tests")
|
||||
def test_pool_set_to_true(self):
|
||||
new_connection = no_pool_connection(alias="default_pool")
|
||||
new_connection.settings_dict["OPTIONS"]["pool"] = True
|
||||
@ -94,7 +88,6 @@ class Tests(TestCase):
|
||||
finally:
|
||||
new_connection.close_pool()
|
||||
|
||||
@unittest.skipUnless(is_oracledb, "Pool specific tests")
|
||||
def test_pool_reuse(self):
|
||||
new_connection = no_pool_connection(alias="default_pool")
|
||||
new_connection.settings_dict["OPTIONS"]["pool"] = {
|
||||
@ -128,7 +121,6 @@ class Tests(TestCase):
|
||||
conn.close()
|
||||
new_connection.close_pool()
|
||||
|
||||
@unittest.skipUnless(is_oracledb, "Pool specific tests")
|
||||
def test_cannot_open_new_connection_in_atomic_block(self):
|
||||
new_connection = no_pool_connection(alias="default_pool")
|
||||
new_connection.settings_dict["OPTIONS"]["pool"] = True
|
||||
@ -138,7 +130,6 @@ class Tests(TestCase):
|
||||
with self.assertRaisesMessage(ProgrammingError, msg):
|
||||
new_connection.ensure_connection()
|
||||
|
||||
@unittest.skipUnless(is_oracledb, "Pool specific tests")
|
||||
def test_pooling_not_support_persistent_connections(self):
|
||||
new_connection = no_pool_connection(alias="default_pool")
|
||||
new_connection.settings_dict["OPTIONS"]["pool"] = True
|
||||
@ -147,48 +138,11 @@ class Tests(TestCase):
|
||||
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||
new_connection.pool
|
||||
|
||||
@unittest.skipIf(is_oracledb, "cx_oracle specific tests")
|
||||
def test_cx_Oracle_not_support_pooling(self):
|
||||
new_connection = no_pool_connection()
|
||||
new_connection.settings_dict["OPTIONS"]["pool"] = True
|
||||
msg = "Pooling isn't supported by cx_Oracle. Use python-oracledb instead."
|
||||
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||
new_connection.connect()
|
||||
|
||||
|
||||
@unittest.skipUnless(connection.vendor == "oracle", "Oracle tests")
|
||||
class TransactionalTests(TransactionTestCase):
|
||||
available_apps = ["backends"]
|
||||
|
||||
def test_hidden_no_data_found_exception(self):
|
||||
# "ORA-1403: no data found" exception is hidden by Oracle OCI library
|
||||
# when an INSERT statement is used with a RETURNING clause (see #28859).
|
||||
with connection.cursor() as cursor:
|
||||
# Create trigger that raises "ORA-1403: no data found".
|
||||
cursor.execute(
|
||||
"""
|
||||
CREATE OR REPLACE TRIGGER "TRG_NO_DATA_FOUND"
|
||||
AFTER INSERT ON "BACKENDS_SQUARE"
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
RAISE NO_DATA_FOUND;
|
||||
END;
|
||||
"""
|
||||
)
|
||||
try:
|
||||
with self.assertRaisesMessage(
|
||||
DatabaseError,
|
||||
(
|
||||
'The database did not return a new row id. Probably "ORA-1403: no '
|
||||
'data found" was raised internally but was hidden by the Oracle '
|
||||
"OCI library (see https://code.djangoproject.com/ticket/28859)."
|
||||
),
|
||||
):
|
||||
Square.objects.create(root=2, square=4)
|
||||
finally:
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute('DROP TRIGGER "TRG_NO_DATA_FOUND"')
|
||||
|
||||
def test_password_with_at_sign(self):
|
||||
from django.db.backends.oracle.base import Database
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user