diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-09-19 18:06:23 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-09-19 18:06:23 -0400 |
commit | 3dfcb10befc7a8c193ee992bdea009e39b2e798c (patch) | |
tree | d53e5285a9838cf1e7687e4a0c6b7a33ab94b468 | |
parent | 80aeba3d5e0269eb689d991ca0b8e281715113ed (diff) | |
download | sqlalchemy-3dfcb10befc7a8c193ee992bdea009e39b2e798c.tar.gz |
- The ``legacy_schema_aliasing`` flag, introduced in version 1.0.5
as part of :ticket:`3424` to allow disabling of the MSSQL dialect's
attempts to create aliases for schema-qualified tables, now defaults
to False; the old behavior is now disabled unless explicitly turned on.
fixes #3434
-rw-r--r-- | doc/build/changelog/changelog_11.rst | 13 | ||||
-rw-r--r-- | doc/build/changelog/migration_11.rst | 36 | ||||
-rw-r--r-- | lib/sqlalchemy/dialects/mssql/base.py | 104 | ||||
-rw-r--r-- | test/dialect/mssql/test_compiler.py | 2 | ||||
-rw-r--r-- | test/dialect/mssql/test_query.py | 16 | ||||
-rw-r--r-- | test/dialect/mssql/test_reflection.py | 4 |
6 files changed, 96 insertions, 79 deletions
diff --git a/doc/build/changelog/changelog_11.rst b/doc/build/changelog/changelog_11.rst index e20e0b4ca..e37fd1a69 100644 --- a/doc/build/changelog/changelog_11.rst +++ b/doc/build/changelog/changelog_11.rst @@ -22,6 +22,19 @@ :version: 1.1.0b1 .. change:: + :tags: change, mssql + :tickets: 3434 + + The ``legacy_schema_aliasing`` flag, introduced in version 1.0.5 + as part of :ticket:`3424` to allow disabling of the MSSQL dialect's + attempts to create aliases for schema-qualified tables, now defaults + to False; the old behavior is now disabled unless explicitly turned on. + + .. seealso:: + + :ref:`change_3434` + + .. change:: :tags: bug, orm :tickets: 3250 diff --git a/doc/build/changelog/migration_11.rst b/doc/build/changelog/migration_11.rst index 81c438e06..ca6c44165 100644 --- a/doc/build/changelog/migration_11.rst +++ b/doc/build/changelog/migration_11.rst @@ -831,5 +831,41 @@ the same thing. :ticket:`3504` +.. _change_3434: + +The legacy_schema_aliasing flag is now set to False +--------------------------------------------------- + +SQLAlchemy 1.0.5 introduced the ``legacy_schema_aliasing`` flag to the +MSSQL dialect, allowing so-called "legacy mode" aliasing to be turned off. +This aliasing attempts to turn schema-qualified tables into aliases; +given a table such as:: + + account_table = Table( + 'account', metadata, + Column('id', Integer, primary_key=True), + Column('info', String(100)), + schema="customer_schema" + ) + +The legacy mode of behavior will attempt to turn a schema-qualified table +name into an alias:: + + >>> eng = create_engine("mssql+pymssql://mydsn", legacy_schema_aliasing=True) + >>> print(account_table.select().compile(eng)) + SELECT account_1.id, account_1.info + FROM customer_schema.account AS account_1 + +However, this aliasing has been shown to be unnecessary and in many cases +produces incorrect SQL. + +In SQLAlchemy 1.1, the ``legacy_schema_aliasing`` flag now defaults to +False, disabling this mode of behavior and allowing the MSSQL dialect to behave +normally with schema-qualified tables. For applications which may rely +on this behavior, set the flag back to True. + + +:ticket:`3434` + Dialect Improvements and Changes - Oracle ============================================= diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py index 6670a28bd..e4f9ac3de 100644 --- a/lib/sqlalchemy/dialects/mssql/base.py +++ b/lib/sqlalchemy/dialects/mssql/base.py @@ -166,56 +166,6 @@ how SQLAlchemy handles this: This is an auxilliary use case suitable for testing and bulk insert scenarios. -.. _legacy_schema_rendering: - -Rendering of SQL statements that include schema qualifiers ---------------------------------------------------------- - -When using :class:`.Table` metadata that includes a "schema" qualifier, -such as:: - - account_table = Table( - 'account', metadata, - Column('id', Integer, primary_key=True), - Column('info', String(100)), - schema="customer_schema" - ) - -The SQL Server dialect has a long-standing behavior that it will attempt -to turn a schema-qualified table name into an alias, such as:: - - >>> eng = create_engine("mssql+pymssql://mydsn") - >>> print(account_table.select().compile(eng)) - SELECT account_1.id, account_1.info - FROM customer_schema.account AS account_1 - -This behavior is legacy, does not function correctly for many forms -of SQL statements, and will be disabled by default in the 1.1 series -of SQLAlchemy. As of 1.0.5, the above statement will produce the following -warning:: - - SAWarning: legacy_schema_aliasing flag is defaulted to True; - some schema-qualified queries may not function correctly. - Consider setting this flag to False for modern SQL Server versions; - this flag will default to False in version 1.1 - -This warning encourages the :class:`.Engine` to be created as follows:: - - >>> eng = create_engine("mssql+pymssql://mydsn", legacy_schema_aliasing=False) - -Where the above SELECT statement will produce:: - - >>> print(account_table.select().compile(eng)) - SELECT customer_schema.account.id, customer_schema.account.info - FROM customer_schema.account - -The warning will not emit if the ``legacy_schema_aliasing`` flag is set -to either True or False. - -.. versionadded:: 1.0.5 - Added the ``legacy_schema_aliasing`` flag to disable - the SQL Server dialect's legacy behavior with schema-qualified table - names. This flag will default to False in version 1.1. - Collation Support ----------------- @@ -322,6 +272,41 @@ behavior of this flag is as follows: .. versionadded:: 1.0.0 +.. _legacy_schema_rendering: + +Legacy Schema Mode +------------------ + +Very old versions of the MSSQL dialect introduced the behavior such that a +schema-qualified table would be auto-aliased when used in a +SELECT statement; given a table:: + + account_table = Table( + 'account', metadata, + Column('id', Integer, primary_key=True), + Column('info', String(100)), + schema="customer_schema" + ) + +this legacy mode of rendering would assume that "customer_schema.account" +would not be accepted by all parts of the SQL statement, as illustrated +below:: + + >>> eng = create_engine("mssql+pymssql://mydsn", legacy_schema_aliasing=True) + >>> print(account_table.select().compile(eng)) + SELECT account_1.id, account_1.info + FROM customer_schema.account AS account_1 + +This mode of behavior is now off by default, as it appears to have served +no purpose; however in the case that legacy applications rely upon it, +it is available using the ``legacy_schema_aliasing`` argument to +:func:`.create_engine` as illustrated above. + +.. versionchanged:: 1.1 the ``legacy_schema_aliasing`` flag introduced + in version 1.0.5 to allow disabling of legacy mode for schemas now + defaults to False. + + .. _mssql_indexes: Clustered Index Support @@ -1156,15 +1141,6 @@ class MSSQLCompiler(compiler.SQLCompiler): def _schema_aliased_table(self, table): if getattr(table, 'schema', None) is not None: - if self.dialect._warn_schema_aliasing and \ - table.schema.lower() != 'information_schema': - util.warn( - "legacy_schema_aliasing flag is defaulted to True; " - "some schema-qualified queries may not function " - "correctly. Consider setting this flag to False for " - "modern SQL Server versions; this flag will default to " - "False in version 1.1") - if table not in self.tablealiases: self.tablealiases[table] = table.alias() return self.tablealiases[table] @@ -1530,7 +1506,7 @@ class MSDialect(default.DefaultDialect): max_identifier_length=None, schema_name="dbo", deprecate_large_types=None, - legacy_schema_aliasing=None, **opts): + legacy_schema_aliasing=False, **opts): self.query_timeout = int(query_timeout or 0) self.schema_name = schema_name @@ -1538,13 +1514,7 @@ class MSDialect(default.DefaultDialect): self.max_identifier_length = int(max_identifier_length or 0) or \ self.max_identifier_length self.deprecate_large_types = deprecate_large_types - - if legacy_schema_aliasing is None: - self.legacy_schema_aliasing = True - self._warn_schema_aliasing = True - else: - self.legacy_schema_aliasing = legacy_schema_aliasing - self._warn_schema_aliasing = False + self.legacy_schema_aliasing = legacy_schema_aliasing super(MSDialect, self).__init__(**opts) diff --git a/test/dialect/mssql/test_compiler.py b/test/dialect/mssql/test_compiler.py index 9d89f040b..80be9f67d 100644 --- a/test/dialect/mssql/test_compiler.py +++ b/test/dialect/mssql/test_compiler.py @@ -12,7 +12,7 @@ from sqlalchemy import Integer, String, Table, Column, select, MetaData,\ class CompileTest(fixtures.TestBase, AssertsCompiledSQL): - __dialect__ = mssql.dialect(legacy_schema_aliasing=False) + __dialect__ = mssql.dialect() def test_true_false(self): self.assert_compile( diff --git a/test/dialect/mssql/test_query.py b/test/dialect/mssql/test_query.py index 61ae32ef4..32edfd7eb 100644 --- a/test/dialect/mssql/test_query.py +++ b/test/dialect/mssql/test_query.py @@ -41,17 +41,15 @@ class LegacySchemaAliasingTest(fixtures.TestBase, AssertsCompiledSQL): ) def _assert_sql(self, element, legacy_sql, modern_sql=None): - dialect = mssql.dialect() + dialect = mssql.dialect(legacy_schema_aliasing=True) - with assertions.expect_warnings( - "legacy_schema_aliasing flag is defaulted to True.*"): - self.assert_compile( - element, - legacy_sql, - dialect=dialect - ) + self.assert_compile( + element, + legacy_sql, + dialect=dialect + ) - dialect = mssql.dialect(legacy_schema_aliasing=False) + dialect = mssql.dialect() self.assert_compile( element, modern_sql or "foob", diff --git a/test/dialect/mssql/test_reflection.py b/test/dialect/mssql/test_reflection.py index daf8af724..e016a6e41 100644 --- a/test/dialect/mssql/test_reflection.py +++ b/test/dialect/mssql/test_reflection.py @@ -213,7 +213,7 @@ class InfoCoerceUnicodeTest(fixtures.TestBase, AssertsCompiledSQL): stmt = tables.c.table_name == 'somename' self.assert_compile( stmt, - "[TABLES_1].[TABLE_NAME] = :table_name_1", + "[INFORMATION_SCHEMA].[TABLES].[TABLE_NAME] = :table_name_1", dialect=dialect ) @@ -223,7 +223,7 @@ class InfoCoerceUnicodeTest(fixtures.TestBase, AssertsCompiledSQL): stmt = tables.c.table_name == 'somename' self.assert_compile( stmt, - "[TABLES_1].[TABLE_NAME] = CAST(:table_name_1 AS NVARCHAR(max))", + "[INFORMATION_SCHEMA].[TABLES].[TABLE_NAME] = CAST(:table_name_1 AS NVARCHAR(max))", dialect=dialect ) |