]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
test fixes for oracle 18c, for rel_1_3
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 18 Dec 2020 15:46:20 +0000 (10:46 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 26 Dec 2020 20:25:06 +0000 (15:25 -0500)
Change-Id: I4968aa3bde3c4d11d7fe84f18b4a846ba357d16a

lib/sqlalchemy/dialects/oracle/base.py
lib/sqlalchemy/dialects/oracle/provision.py
lib/sqlalchemy/testing/plugin/plugin_base.py
lib/sqlalchemy/testing/provision.py
lib/sqlalchemy/testing/warnings.py
test/dialect/oracle/test_dialect.py
test/dialect/oracle/test_reflection.py

index 3028704a4ff7ef2294558a72376e1823801b8e17..c60a85c7cff7b4afa6eaed1f3c7e5c21ab14afe9 100644 (file)
@@ -974,7 +974,11 @@ class OracleCompiler(compiler.SQLCompiler):
         for i, column in enumerate(
             expression._select_iterables(returning_cols)
         ):
-            if self.isupdate and isinstance(column.server_default, Computed):
+            if (
+                self.isupdate
+                and isinstance(column.server_default, Computed)
+                and not self.dialect._supports_update_returning_computed_cols
+            ):
                 util.warn(
                     "Computed columns don't work with Oracle UPDATE "
                     "statements that use RETURNING; the value of the column "
@@ -1388,6 +1392,12 @@ class OracleDialect(default.DefaultDialect):
     def _supports_char_length(self):
         return not self._is_oracle_8
 
+    @property
+    def _supports_update_returning_computed_cols(self):
+        # on version 18 this error is no longet present while it happens on 11
+        # it may work also on versions before the 18
+        return self.server_version_info and self.server_version_info >= (18,)
+
     def do_release_savepoint(self, connection, name):
         # Oracle does not support RELEASE SAVEPOINT
         pass
index 7901eb4e813bc62439b385f6f317294cffa84a67..bf6116b07afa6f1e1f6476a0909d9c96a641e955 100644 (file)
@@ -7,6 +7,7 @@ from ...testing.provision import drop_db
 from ...testing.provision import follower_url_from_main
 from ...testing.provision import log
 from ...testing.provision import run_reap_dbs
+from ...testing.provision import stop_test_class
 from ...testing.provision import temp_table_keyword_args
 from ...testing.provision import update_db_opts
 
@@ -60,6 +61,18 @@ def _oracle_update_db_opts(db_url, db_opts):
     pass
 
 
+@stop_test_class.for_db("oracle")
+def stop_test_class(config, db, cls):
+    """run magic command to get rid of identity sequences
+
+    # https://floo.bar/2019/11/29/drop-the-underlying-sequence-of-an-identity-column/
+
+    """
+
+    with db.begin() as conn:
+        conn.execute("purge recyclebin")
+
+
 @run_reap_dbs.for_db("oracle")
 def _reap_oracle_dbs(url, idents):
     log.info("db reaper connecting to %r", url)
index 2b062cee4a2736900221bc67fc6624a73dc2d349..f1314d96c98cadc5415f4f2681576188c22fd1e5 100644 (file)
@@ -41,6 +41,7 @@ engines = None
 exclusions = None
 warnings = None
 profiling = None
+provision = None
 assertions = None
 requirements = None
 config = None
@@ -246,12 +247,12 @@ def post_begin():
         fn(options, file_config)
 
     # late imports, has to happen after config.
-    global util, fixtures, engines, exclusions, assertions
+    global util, fixtures, engines, exclusions, assertions, provision
     global warnings, profiling, config, testing
     from sqlalchemy import testing  # noqa
     from sqlalchemy.testing import fixtures, engines, exclusions  # noqa
     from sqlalchemy.testing import assertions, warnings, profiling  # noqa
-    from sqlalchemy.testing import config  # noqa
+    from sqlalchemy.testing import config, provision  # noqa
     from sqlalchemy import util  # noqa
 
     warnings.setup_filters()
@@ -554,6 +555,8 @@ def start_test_class(cls):
 def stop_test_class(cls):
     # from sqlalchemy import inspect
     # assert not inspect(testing.db).get_table_names()
+
+    provision.stop_test_class(config, config.db, cls)
     engines.testing_reaper._stop_test_ctx()
     try:
         if not options.low_connections:
index 7669cdc32e0e852f794c7871f7d5f3953af42f53..2445b7745e99980bb1bc38e912b8490cc71e8fdc 100644 (file)
@@ -192,3 +192,8 @@ def temp_table_keyword_args(cfg, eng):
     raise NotImplementedError(
         "no temp table keyword args routine for cfg: %s" % eng.url
     )
+
+
+@register.init
+def stop_test_class(config, db, testcls):
+    pass
index 6bb89a3cf85b318695504f8e5eb08fa5d66a123a..1034b94d899f73fc73aed6d2fccbf683e02c0acd 100644 (file)
@@ -25,8 +25,7 @@ def setup_filters():
     warnings.filterwarnings(
         "ignore",
         category=sa_exc.SAWarning,
-        message=r"Oracle compatibility version .* is known to have a "
-        "maximum identifier",
+        message=r"Oracle version .* is known to have a " "maximum identifier",
     )
 
     # some selected deprecations...
index c28218a3d36632ee35ab973e3d4a68cbf2ae55da..d01e1be2e7cf56526c9299fa542d49b741e02d2b 100644 (file)
@@ -350,11 +350,17 @@ class ComputedReturningTest(fixtures.TablesTest):
 
             eq_(conn.scalar(select([test.c.bar])), 47)
 
-    def test_computed_update_warning(self):
+    def test_computed_update_warning(self, connection):
         test = self.tables.test
-        with testing.db.connect() as conn:
-            conn.execute(test.insert(), {"id": 1, "foo": 5})
+        conn = connection
+        conn.execute(test.insert(), {"id": 1, "foo": 5})
 
+        if testing.db.dialect._supports_update_returning_computed_cols:
+            result = conn.execute(
+                test.update().values(foo=10).return_defaults()
+            )
+            eq_(result.returned_defaults, (52,))
+        else:
             with testing.expect_warnings(
                 "Computed columns don't work with Oracle UPDATE"
             ):
@@ -365,7 +371,7 @@ class ComputedReturningTest(fixtures.TablesTest):
                 # returns the *old* value
                 eq_(result.returned_defaults, (47,))
 
-            eq_(conn.scalar(select([test.c.bar])), 52)
+        eq_(conn.scalar(select([test.c.bar])), 52)
 
     def test_computed_update_no_warning(self):
         test = self.tables.test_no_returning
@@ -429,7 +435,7 @@ class QuotedBindRoundTripTest(fixtures.TestBase):
 
     @testing.provide_metadata
     def test_table_round_trip(self):
-        oracle.RESERVED_WORDS.remove("UNION")
+        oracle.RESERVED_WORDS.discard("UNION")
 
         metadata = self.metadata
         table = Table(
index 4ce60db4c36dfd5fcf144264806ddad2bd1b370a..160b58939ddcecefd31b9b7c03df4e34d1095c92 100644 (file)
@@ -456,27 +456,24 @@ class UnsupportedIndexReflectTest(fixtures.TestBase):
 
 
 def all_tables_compression_missing():
-    try:
-        testing.db.execute("SELECT compression FROM all_tables")
-        if "Enterprise Edition" not in testing.db.scalar(
-            "select * from v$version"
-        ):
+    with testing.db.connect() as conn:
+        if (
+            "Enterprise Edition"
+            not in conn.execute("select * from v$version").scalar()
+            # this works in Oracle Database 18c Express Edition Release
+        ) and testing.db.dialect.server_version_info < (18,):
             return True
         return False
-    except Exception:
-        return True
 
 
 def all_tables_compress_for_missing():
-    try:
-        testing.db.execute("SELECT compress_for FROM all_tables")
-        if "Enterprise Edition" not in testing.db.scalar(
-            "select * from v$version"
+    with testing.db.connect() as conn:
+        if (
+            "Enterprise Edition"
+            not in conn.execute("select * from v$version").scalar()
         ):
             return True
         return False
-    except Exception:
-        return True
 
 
 class TableReflectionTest(fixtures.TestBase):