1
0
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:
Sarah Boyce 2024-12-12 17:56:14 +01:00
parent 0a0f9b4acc
commit b4bc393b23
10 changed files with 12 additions and 103 deletions

View File

@ -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):

View File

@ -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

View File

@ -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"]

View File

@ -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

View File

@ -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")

View File

@ -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)

View File

@ -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

View File

@ -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/

View File

@ -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.

View File

@ -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