diff --git a/django/db/backends/base/introspection.py b/django/db/backends/base/introspection.py
index cefdecea0a..52da90b7e9 100644
--- a/django/db/backends/base/introspection.py
+++ b/django/db/backends/base/introspection.py
@@ -40,6 +40,14 @@ class BaseDatabaseIntrospection:
         """
         return self.table_name_converter(name)
 
+    def identifier_converter(self, name):
+        """
+        Apply a conversion to the identifier for the purposes of comparison.
+
+        Use table_name_converter() by default.
+        """
+        return self.table_name_converter(name)
+
     def table_names(self, cursor=None, include_views=False):
         """
         Return a list of names of all tables that exist in the database.
diff --git a/django/db/backends/oracle/introspection.py b/django/db/backends/oracle/introspection.py
index e5597fd56c..a2da8325fe 100644
--- a/django/db/backends/oracle/introspection.py
+++ b/django/db/backends/oracle/introspection.py
@@ -186,6 +186,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
             GROUP BY user_constraints.constraint_name, user_constraints.constraint_type
         """, [table_name])
         for constraint, columns, pk, unique, check in cursor.fetchall():
+            constraint = self.identifier_converter(constraint)
             constraints[constraint] = {
                 'columns': columns.split(','),
                 'primary_key': pk,
@@ -213,6 +214,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
             GROUP BY cons.constraint_name, rcols.table_name, rcols.column_name
         """, [table_name])
         for constraint, columns, other_table, other_column in cursor.fetchall():
+            constraint = self.identifier_converter(constraint)
             constraints[constraint] = {
                 'primary_key': False,
                 'unique': False,
@@ -240,6 +242,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
             GROUP BY ind.index_name, ind.index_type
         """, [table_name])
         for constraint, type_, columns, orders in cursor.fetchall():
+            constraint = self.identifier_converter(constraint)
             constraints[constraint] = {
                 'primary_key': False,
                 'unique': False,
diff --git a/docs/releases/2.2.txt b/docs/releases/2.2.txt
index 4dd3c72e20..8d832e05fb 100644
--- a/docs/releases/2.2.txt
+++ b/docs/releases/2.2.txt
@@ -293,6 +293,9 @@ Database backend API
 * Third party database backends must implement support for partial indexes or
   set ``DatabaseFeatures.supports_partial_indexes`` to ``False``.
 
+* ``DatabaseIntrospection.get_constraints()`` must return lower name constraint
+  names, even when ``DatabaseFeatures.uppercases_column_names`` is ``True``.
+
 Admin actions are no longer collected from base ``ModelAdmin`` classes
 ----------------------------------------------------------------------
 
diff --git a/tests/schema/tests.py b/tests/schema/tests.py
index 7f170c863e..d9dda84fec 100644
--- a/tests/schema/tests.py
+++ b/tests/schema/tests.py
@@ -1868,9 +1868,6 @@ class SchemaTests(TransactionTestCase):
                 table_name=AuthorWithIndexedName._meta.db_table,
                 column_names=('name',),
             )
-        if connection.features.uppercases_column_names:
-            author_index_name = author_index_name.upper()
-            db_index_name = db_index_name.upper()
         try:
             AuthorWithIndexedName._meta.indexes = [index]
             with connection.schema_editor() as editor:
@@ -1908,8 +1905,6 @@ class SchemaTests(TransactionTestCase):
         with connection.schema_editor() as editor:
             editor.add_index(Author, index)
         if connection.features.supports_index_column_ordering:
-            if connection.features.uppercases_column_names:
-                index_name = index_name.upper()
             self.assertIndexOrder(Author._meta.db_table, index_name, ['ASC', 'DESC'])
         # Drop the index
         with connection.schema_editor() as editor:
@@ -2127,7 +2122,8 @@ class SchemaTests(TransactionTestCase):
             editor.create_model(model)
             editor.add_field(model, field)
 
-            constraint_name = "CamelCaseIndex"
+            constraint_name = 'CamelCaseIndex'
+            expected_constraint_name = constraint_name.lower()
             editor.execute(
                 editor.sql_create_index % {
                     "table": editor.quote_name(table),
@@ -2138,13 +2134,12 @@ class SchemaTests(TransactionTestCase):
                     "condition": "",
                 }
             )
-            if connection.features.uppercases_column_names:
-                constraint_name = constraint_name.upper()
-            self.assertIn(constraint_name, self.get_constraints(model._meta.db_table))
+            self.assertIn(expected_constraint_name, self.get_constraints(model._meta.db_table))
             editor.alter_field(model, get_field(db_index=True), field, strict=True)
-            self.assertNotIn(constraint_name, self.get_constraints(model._meta.db_table))
+            self.assertNotIn(expected_constraint_name, self.get_constraints(model._meta.db_table))
 
             constraint_name = "CamelCaseUniqConstraint"
+            expected_constraint_name = constraint_name.lower()
             editor.execute(
                 editor.sql_create_unique % {
                     "table": editor.quote_name(table),
@@ -2152,14 +2147,13 @@ class SchemaTests(TransactionTestCase):
                     "columns": editor.quote_name(field.column),
                 }
             )
-            if connection.features.uppercases_column_names:
-                constraint_name = constraint_name.upper()
-            self.assertIn(constraint_name, self.get_constraints(model._meta.db_table))
+            self.assertIn(expected_constraint_name, self.get_constraints(model._meta.db_table))
             editor.alter_field(model, get_field(unique=True), field, strict=True)
-            self.assertNotIn(constraint_name, self.get_constraints(model._meta.db_table))
+            self.assertNotIn(expected_constraint_name, self.get_constraints(model._meta.db_table))
 
             if editor.sql_create_fk:
                 constraint_name = "CamelCaseFKConstraint"
+                expected_constraint_name = constraint_name.lower()
                 editor.execute(
                     editor.sql_create_fk % {
                         "table": editor.quote_name(table),
@@ -2170,11 +2164,9 @@ class SchemaTests(TransactionTestCase):
                         "deferrable": connection.ops.deferrable_sql(),
                     }
                 )
-                if connection.features.uppercases_column_names:
-                    constraint_name = constraint_name.upper()
-                self.assertIn(constraint_name, self.get_constraints(model._meta.db_table))
+                self.assertIn(expected_constraint_name, self.get_constraints(model._meta.db_table))
                 editor.alter_field(model, get_field(Author, CASCADE, field_class=ForeignKey), field, strict=True)
-                self.assertNotIn(constraint_name, self.get_constraints(model._meta.db_table))
+                self.assertNotIn(expected_constraint_name, self.get_constraints(model._meta.db_table))
 
     def test_add_field_use_effective_default(self):
         """
@@ -2491,12 +2483,7 @@ class SchemaTests(TransactionTestCase):
         new_field.set_attributes_from_name('weight')
         with connection.schema_editor() as editor:
             editor.alter_field(Author, old_field, new_field, strict=True)
-
-        expected = 'schema_author_weight_587740f9'
-        if connection.features.uppercases_column_names:
-            expected = expected.upper()
-        self.assertEqual(self.get_constraints_for_column(Author, 'weight'), [expected])
-
+        self.assertEqual(self.get_constraints_for_column(Author, 'weight'), ['schema_author_weight_587740f9'])
         # Remove db_index=True to drop index.
         with connection.schema_editor() as editor:
             editor.alter_field(Author, new_field, old_field, strict=True)
