]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Add support for Azure authentication options
authorGord Thompson <gord@gordthompson.com>
Thu, 17 Sep 2020 16:32:31 +0000 (10:32 -0600)
committerGord Thompson <gord@gordthompson.com>
Thu, 17 Sep 2020 17:42:06 +0000 (11:42 -0600)
Fixes: #5592
Change-Id: I0688e5ea0fc6b01a0b72f397daea8f57a2ec0766

doc/build/changelog/unreleased_13/5592.rst [new file with mode: 0644]
lib/sqlalchemy/connectors/pyodbc.py
lib/sqlalchemy/dialects/mssql/pyodbc.py
test/dialect/mssql/test_engine.py

diff --git a/doc/build/changelog/unreleased_13/5592.rst b/doc/build/changelog/unreleased_13/5592.rst
new file mode 100644 (file)
index 0000000..294fadf
--- /dev/null
@@ -0,0 +1,8 @@
+.. change::
+    :tags: bug, mssql
+    :tickets: 5592
+
+    Fixed issue where a SQLAlchemy connection URI for Azure DW with
+    ``authentication=ActiveDirectoryIntegrated`` (and no username+password)
+    was not constructing the ODBC connection string in a way that was
+    acceptable to the Azure DW instance.
index 96ac0c1f1ed4c754ed444428a3f563020511775e..e1a7c99f4db2ffbe0817954c1d7b9f95ff530ef1 100644 (file)
@@ -95,9 +95,15 @@ class PyODBCConnector(Connector):
             user = keys.pop("user", None)
             if user:
                 connectors.append("UID=%s" % user)
-                connectors.append("PWD=%s" % keys.pop("password", ""))
+                pwd = keys.pop("password", "")
+                if pwd:
+                    connectors.append("PWD=%s" % pwd)
             else:
-                connectors.append("Trusted_Connection=Yes")
+                authentication = keys.pop("authentication", None)
+                if authentication:
+                    connectors.append("Authentication=%s" % authentication)
+                else:
+                    connectors.append("Trusted_Connection=Yes")
 
             # if set to 'Yes', the ODBC layer will try to automagically
             # convert textual data from your database encoding to your
index df340bbcacd34671e6b3b6df98aa482439f7cc9b..8bc318ea03aeb34851c1f448f4e3664c1c85c64d 100644 (file)
@@ -52,7 +52,8 @@ name must be URL encoded which means using plus signs for spaces::
 
 Other keywords interpreted by the Pyodbc dialect to be passed to
 ``pyodbc.connect()`` in both the DSN and hostname cases include:
-``odbc_autotranslate``, ``ansi``, ``unicode_results``, ``autocommit``.
+``odbc_autotranslate``, ``ansi``, ``unicode_results``, ``autocommit``, 
+``authentication`` (e.g., ``authentication=ActiveDirectoryIntegrated``).
 Note that in order for the dialect to recognize these keywords
 (including the ``driver`` keyword above) they must be all lowercase.
 
index 27e92d5b5c1f3f8adbb07ef831d2863f40fd934e..a29d49c4ce8ab304848d89b9451169638dba6ee1 100644 (file)
@@ -156,6 +156,26 @@ class ParseConnectTest(fixtures.TestBase):
             True,
         )
 
+    def test_pyodbc_extra_connect_azure(self):
+        # issue #5592
+        dialect = pyodbc.dialect()
+        u = url.make_url(
+            "mssql+pyodbc://@server_name/db_name?"
+            "driver=ODBC+Driver+17+for+SQL+Server;"
+            "authentication=ActiveDirectoryIntegrated"
+        )
+        connection = dialect.create_connect_args(u)
+        eq_(connection[1], {})
+        eq_(
+            connection[0][0]
+            in (
+                "DRIVER={ODBC Driver 17 for SQL Server};"
+                "Server=server_name;Database=db_name;"
+                "Authentication=ActiveDirectoryIntegrated",
+            ),
+            True,
+        )
+
     def test_pyodbc_odbc_connect(self):
         dialect = pyodbc.dialect()
         u = url.make_url(