From: Mike Bayer Date: Sun, 23 Oct 2022 14:34:33 +0000 (-0400) Subject: test support for has_table()->view; backport to 1.4 X-Git-Tag: rel_1_4_43~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f710836488162518dcf2dc1006d90ecd77a2a178;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git test support for has_table()->view; backport to 1.4 For 1.4 only; in 2.0 this just refines the test suite a bit. Fixed regression which occurred throughout the 1.4 series where the :meth:`.Inspector.has_table` method, which historically reported on views as well, stopped working for SQL Server. The method never worked for Oracle in this way, so for compatibility within the 1.4 series, Oracle's dialect remains returning False for ``has_table()`` against a view within the 1.4 series. The issue is not present in the 2.0 series which uses a different reflection architecture, where has_table() reports True for views on all backends including SQL Server and Oracle. Test support is added within the 1.4 series to ensure ``has_table()`` remains working per spec re: views. Fixes: #8700 Change-Id: I119a91ec07911edb08cf0799234827fec9ea1195 (cherry picked from commit c02f6b744d304578fe67da2e13d2c02ab71140d2) --- diff --git a/doc/build/changelog/unreleased_14/8700.rst b/doc/build/changelog/unreleased_14/8700.rst new file mode 100644 index 0000000000..b9369e038b --- /dev/null +++ b/doc/build/changelog/unreleased_14/8700.rst @@ -0,0 +1,15 @@ +.. change:: + :tags: bug, mssql, reflection + :tickets: 8700 + + Fixed regression which occurred throughout the 1.4 series where the + :meth:`.Inspector.has_table` method, which historically reported on views + as well, stopped working for SQL Server. The method never worked for + Oracle in this way, so for compatibility within the 1.4 series, + Oracle's dialect remains returning False for ``has_table()`` against a + view within the 1.4 series. + + The issue is not present in the 2.0 series which uses a different + reflection architecture, where has_table() reports True for views on all + backends including SQL Server and Oracle. Test support is added within the + 1.4 series to ensure ``has_table()`` remains working per spec re: views. diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py index 0c967b5167..738ff7ce34 100644 --- a/lib/sqlalchemy/dialects/mssql/base.py +++ b/lib/sqlalchemy/dialects/mssql/base.py @@ -2959,11 +2959,8 @@ class MSDialect(default.DefaultDialect): else: tables = ischema.tables - s = sql.select(tables.c.table_name).where( - sql.and_( - tables.c.table_type == "BASE TABLE", - tables.c.table_name == tablename, - ) + s = sql.select(tables.c.table_name, tables.c.table_type).where( + tables.c.table_name == tablename, ) if owner: diff --git a/lib/sqlalchemy/testing/suite/test_reflection.py b/lib/sqlalchemy/testing/suite/test_reflection.py index 459a4d8211..ff98f18c07 100644 --- a/lib/sqlalchemy/testing/suite/test_reflection.py +++ b/lib/sqlalchemy/testing/suite/test_reflection.py @@ -53,6 +53,28 @@ class HasTableTest(fixtures.TablesTest): schema=config.test_schema, ) + if testing.requires.view_reflection: + cls.define_views(metadata) + + @classmethod + def define_views(cls, metadata): + query = "CREATE VIEW vv AS SELECT * FROM test_table" + + event.listen(metadata, "after_create", DDL(query)) + event.listen(metadata, "before_drop", DDL("DROP VIEW vv")) + + if testing.requires.schemas.enabled: + query = "CREATE VIEW %s.vv AS SELECT * FROM %s.test_table_s" % ( + config.test_schema, + config.test_schema, + ) + event.listen(metadata, "after_create", DDL(query)) + event.listen( + metadata, + "before_drop", + DDL("DROP VIEW %s.vv" % (config.test_schema)), + ) + def test_has_table(self): with config.db.begin() as conn: is_true(config.db.dialect.has_table(conn, "test_table")) @@ -78,6 +100,27 @@ class HasTableTest(fixtures.TablesTest): ) ) + @testing.fails_on( + "oracle", + "per #8700 this remains at its previous behavior of not " + "working within 1.4.", + ) + @testing.requires.views + def test_has_table_view(self, connection): + insp = inspect(connection) + is_true(insp.has_table("vv")) + + @testing.fails_on( + "oracle", + "per #8700 this remains at its previous behavior of not " + "working within 1.4", + ) + @testing.requires.views + @testing.requires.schemas + def test_has_table_view_schema(self, connection): + insp = inspect(connection) + is_true(insp.has_table("vv", config.test_schema)) + class HasIndexTest(fixtures.TablesTest): __backend__ = True