summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2024-12-12 17:56:14 +0100
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2025-01-15 22:28:37 +0100
commitb4bc393b23dd2a222a3ca52b5d44ec33499c789f (patch)
treeaddb335ec4a402e7f4fb15b0d1390ff8688cdfa1
parent0a0f9b4acce5534c1e1da145f80856f5e6b78768 (diff)
Refs #33817 -- Removed support for cx_Oracle per deprecation timeline.
-rw-r--r--django/contrib/gis/db/backends/oracle/adapter.py3
-rw-r--r--django/contrib/gis/db/backends/oracle/introspection.py3
-rw-r--r--django/db/backends/oracle/base.py8
-rw-r--r--django/db/backends/oracle/features.py11
-rw-r--r--django/db/backends/oracle/introspection.py3
-rw-r--r--django/db/backends/oracle/operations.py11
-rw-r--r--django/db/backends/oracle/oracledb_any.py20
-rw-r--r--docs/ref/databases.txt4
-rw-r--r--docs/releases/6.0.txt2
-rw-r--r--tests/backends/oracle/tests.py50
10 files changed, 12 insertions, 103 deletions
diff --git a/django/contrib/gis/db/backends/oracle/adapter.py b/django/contrib/gis/db/backends/oracle/adapter.py
index 0bf11648d9..bd52b1bf21 100644
--- a/django/contrib/gis/db/backends/oracle/adapter.py
+++ b/django/contrib/gis/db/backends/oracle/adapter.py
@@ -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):
diff --git a/django/contrib/gis/db/backends/oracle/introspection.py b/django/contrib/gis/db/backends/oracle/introspection.py
index bf299b12ff..8e1a5e7a8c 100644
--- a/django/contrib/gis/db/backends/oracle/introspection.py
+++ b/django/contrib/gis/db/backends/oracle/introspection.py
@@ -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
diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py
index 3b37c38f97..9fd82dd705 100644
--- a/django/db/backends/oracle/base.py
+++ b/django/db/backends/oracle/base.py
@@ -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"]
diff --git a/django/db/backends/oracle/features.py b/django/db/backends/oracle/features.py
index ad9ab8da55..bf47577ed6 100644
--- a/django/db/backends/oracle/features.py
+++ b/django/db/backends/oracle/features.py
@@ -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
diff --git a/django/db/backends/oracle/introspection.py b/django/db/backends/oracle/introspection.py
index 07c2d9bded..393e6c66d7 100644
--- a/django/db/backends/oracle/introspection.py
+++ b/django/db/backends/oracle/introspection.py
@@ -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")
diff --git a/django/db/backends/oracle/operations.py b/django/db/backends/oracle/operations.py
index 79c6da994e..aa67f28a79 100644
--- a/django/db/backends/oracle/operations.py
+++ b/django/db/backends/oracle/operations.py
@@ -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)
diff --git a/django/db/backends/oracle/oracledb_any.py b/django/db/backends/oracle/oracledb_any.py
deleted file mode 100644
index 22a9b78be8..0000000000
--- a/django/db/backends/oracle/oracledb_any.py
+++ /dev/null
@@ -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
diff --git a/docs/ref/databases.txt b/docs/ref/databases.txt
index b3c429d8a2..217be19728 100644
--- a/docs/ref/databases.txt
+++ b/docs/ref/databases.txt
@@ -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/
diff --git a/docs/releases/6.0.txt b/docs/releases/6.0.txt
index d985e14679..8708e4495a 100644
--- a/docs/releases/6.0.txt
+++ b/docs/releases/6.0.txt
@@ -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.
diff --git a/tests/backends/oracle/tests.py b/tests/backends/oracle/tests.py
index 0c4dbce8ba..aa5555fa2e 100644
--- a/tests/backends/oracle/tests.py
+++ b/tests/backends/oracle/tests.py
@@ -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