]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Change Oracle max_identifier_length to 128
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 2 Oct 2019 19:37:24 +0000 (15:37 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 2 Oct 2019 22:03:08 +0000 (18:03 -0400)
The max_identifier_length for the Oracle dialect is now 128 characters by
default, unless compatibility version less than 12.2 upon first connect, in
which case the legacy length of 30 characters is used.  This is a
continuation of the issue as committed to the 1.3 series which adds max
identifier length detection upon first connect as well as warns for the
change in Oracle server.

Fixes: #4857
Change-Id: I5b11edaebb54ec7f0e5456a785105838a1d752e5

doc/build/changelog/unreleased_14/4857.rst [new file with mode: 0644]
lib/sqlalchemy/dialects/oracle/base.py
lib/sqlalchemy/testing/warnings.py
test/dialect/oracle/test_compiler.py
test/orm/test_lockmode.py

diff --git a/doc/build/changelog/unreleased_14/4857.rst b/doc/build/changelog/unreleased_14/4857.rst
new file mode 100644 (file)
index 0000000..57ad8d0
--- /dev/null
@@ -0,0 +1,15 @@
+.. change::
+    :tags: usecase, oracle
+    :tickets: 4857
+
+    The max_identifier_length for the Oracle dialect is now 128 characters by
+    default, unless compatibility version less than 12.2 upon first connect, in
+    which case the legacy length of 30 characters is used.  This is a
+    continuation of the issue as committed to the 1.3 series which adds max
+    identifier length detection upon first connect as well as warns for the
+    change in Oracle server.
+
+    .. seealso::
+
+        :ref:`oracle_max_identifier_lengths` - in the Oracle dialect documentation
+
index 957f936e3528e748e5176991b7b7ecf463875a09..d0facb956d86e4732e54fba2dc58910667268159 100644 (file)
@@ -84,27 +84,21 @@ To assist with this change and others, Oracle includes the concept of a
 actual server version in order to assist with migration of Oracle databases,
 and may be configured within the Oracle server itself. This compatibility
 version is retrieved using the query  ``SELECT value FROM v$parameter WHERE
-name = 'compatible';``.   The SQLAlchemy Oracle dialect as of version 1.3.9
+name = 'compatible';``.   The SQLAlchemy Oracle dialect
 will use this query upon first connect in order to determine the effective
 compatibility version of the server, which determines what the maximum allowed
 identifier length is for the server.
 
-For the duration of the SQLAlchemy 1.3 series, the default max identifier
-length will remain at 30, even if compatibility version 12.2 or greater is in
-use.  When the newer version is detected, a warning will be emitted upon first
-connect, which refers the user to make use of the
-:paramref:`.create_engine.max_identifier_length` parameter in order to assure
-forwards compatibility with SQLAlchemy 1.4, which will be changing this value
-to 128 when compatibility version 12.2 or greater is detected.
-
-Using :paramref:`.create_engine.max_identifier_length`, the effective identifier
-length used by the SQLAlchemy dialect will be used as given, overriding the
-current default value of 30, so that when Oracle 12.2 or greater is used, the
-newer identifier length may be taken advantage of::
+As of SQLAlchemy 1.4, the default max identifier length for the Oracle dialect
+is 128 characters.  Upon first connect, the compatibility version is detected
+and if it is less than Oracle version 12.2, the max identifier length is
+changed to be 30 characters.  In all cases, setting the
+:paramref:`.create_engine.max_identifier_length` parameter will bypass this
+change and the value given will be used as is::
 
     engine = create_engine(
         "oracle+cx_oracle://scott:tiger@oracle122",
-        max_identifier_length=128)
+        max_identifier_length=30)
 
 The maximum identifier length comes into play both when generating anonymized
 SQL labels in SELECT statements, but more crucially when generating constraint
@@ -151,25 +145,20 @@ However with length=128, it becomes::
     CREATE INDEX ix_some_column_name_1some_column_name_2some_column_name_3 ON t
     (some_column_name_1, some_column_name_2, some_column_name_3)
 
-The implication here is that by upgrading SQLAlchemy to version 1.4 on
-an existing Oracle 12.2 or greater database, the generation of constraint
-names will change, which can impact the behavior of database migrations.
-A key example is a migration that wishes to "DROP CONSTRAINT" on a name that
-was previously generated with the shorter length.  This migration will fail
-when the identifier length is changed without the name of the index or
-constraint first being adjusted.
-
-Therefore, applications are strongly advised to make use of
+Applications which have run versions of SQLAlchemy prior to 1.4 on an  Oracle
+server version 12.2 or greater are therefore subject to the scenario of a
+database migration that wishes to "DROP CONSTRAINT" on a name that was
+previously generated with the shorter length.  This migration will fail when
+the identifier length is changed without the name of the index or constraint
+first being adjusted.  Such applications are strongly advised to make use of
 :paramref:`.create_engine.max_identifier_length` in order to maintain control
 of the generation of truncated names, and to fully review and test all database
 migrations in a staging environment when changing this value to ensure that the
 impact of this change has been mitigated.
 
-
-.. versionadded:: 1.3.9 Added the
-   :paramref:`.create_engine.max_identifier_length` parameter; the Oracle
-   dialect now detects compatibility version 12.2 or greater and warns
-   about upcoming max identitifier length changes in SQLAlchemy 1.4.
+.. versionchanged:: 1.4 the default max_identifier_length for Oracle is 128
+   characters, which is adjusted down to 30 upon first connect if an older
+   version of Oracle server (compatibility version < 12.2) is detected.
 
 
 LIMIT/OFFSET Support
@@ -1235,7 +1224,7 @@ class OracleDialect(default.DefaultDialect):
     supports_alter = True
     supports_unicode_statements = False
     supports_unicode_binds = False
-    max_identifier_length = 30
+    max_identifier_length = 128
 
     # this should be set to
     # "SELECT value FROM v$parameter WHERE name = 'compatible'"
@@ -1355,22 +1344,8 @@ class OracleDialect(default.DefaultDialect):
         pass
 
     def _check_max_identifier_length(self, connection):
-        if self._effective_compat_server_version_info >= (12, 2):
-            util.warn(
-                "Oracle compatibility version %r is known to have a maximum "
-                "identifier length of 128, rather than the historical default "
-                "of 30. SQLAlchemy 1.4 will use 128 for this "
-                "database; please set max_identifier_length=128 "
-                "in create_engine() in order to "
-                "test the application with this new length, or set to 30 in "
-                "order to assure that 30 continues to be used.  "
-                "In particular, pay close attention to the behavior of "
-                "database migrations as dynamically generated names may "
-                "change. See the section 'Max Identifier Lengths' in the "
-                "SQLAlchemy Oracle dialect documentation for background."
-                % ((self.server_version_info,))
-            )
-            return 128
+        if self._effective_compat_server_version_info < (12, 2):
+            return 30
         else:
             # use the default
             return None
index 7fdcec2792242e6a84adf6cb18aec6f9084130db..829f855863e9c3724ed430d386ebf0486c098571 100644 (file)
@@ -22,13 +22,6 @@ def setup_filters():
     warnings.filterwarnings("error", category=sa_exc.SADeprecationWarning)
     warnings.filterwarnings("error", category=sa_exc.SAWarning)
 
-    warnings.filterwarnings(
-        "ignore",
-        category=sa_exc.SAWarning,
-        message=r"Oracle compatibility version .* is known to have a "
-        "maximum identifier",
-    )
-
     # some selected deprecations...
     warnings.filterwarnings("error", category=DeprecationWarning)
     warnings.filterwarnings(
index a6ea7d2b17a2e81d71a4691d3fdf2be9028c9003..32ef7fd78f23ca595131a8e246c27030a1be8b46 100644 (file)
@@ -664,11 +664,11 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
             checkparams={"param_1": 20, "param_2": 10},
         )
 
-    def test_long_labels(self):
+    def test_long_labels_legacy_ident_length(self):
         dialect = default.DefaultDialect()
         dialect.max_identifier_length = 30
 
-        ora_dialect = oracle.dialect()
+        ora_dialect = oracle.dialect(max_identifier_length=30)
 
         m = MetaData()
         a_table = Table(
index c2b2336b6615276a223ce276c3112c18b57aa22e..bc90c25d89dd2430aee880ef38d49f2e83158f8a 100644 (file)
@@ -338,7 +338,7 @@ class CompileTest(_fixtures.FixtureTest, AssertsCompiledSQL):
             "anon_1.users_name AS anon_1_users_name, "
             "addresses_1.id AS addresses_1_id, "
             "addresses_1.user_id AS addresses_1_user_id, "
-            "addresses_1.email_address AS addresses_1_email_addres_1 "
+            "addresses_1.email_address AS addresses_1_email_address "
             "FROM (SELECT anon_2.users_id AS users_id, "
             "anon_2.users_name AS users_name FROM "
             "(SELECT users.id AS users_id, users.name AS users_name "