]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Pass URL object, not the string, to on_connect_url
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 6 Jun 2021 14:12:05 +0000 (10:12 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 6 Jun 2021 14:12:05 +0000 (10:12 -0400)
The fix for pysqlcipher released in version 1.4.3 :ticket:`5848` was
unfortunately non-working, in that the new ``on_connect_url`` hook was
erroneously not receiving a ``URL`` object under normal usage of
:func:`_sa.create_engine` and instead received a string that was unhandled;
the test suite failed to fully set up the actual conditions under which
this hook is called. This has been fixed.

Fixes: #6586
Change-Id: I3bf738daec35877a10fdad740f08dca9e7420829

doc/build/changelog/unreleased_14/6586.rst [new file with mode: 0644]
lib/sqlalchemy/dialects/sqlite/pysqlcipher.py
lib/sqlalchemy/engine/create.py
test/dialect/test_sqlite.py
test/engine/test_parseconnect.py

diff --git a/doc/build/changelog/unreleased_14/6586.rst b/doc/build/changelog/unreleased_14/6586.rst
new file mode 100644 (file)
index 0000000..027f1b0
--- /dev/null
@@ -0,0 +1,10 @@
+.. change::
+    :tags: bug, sqlite, regression
+    :tickets: 6586
+
+    The fix for pysqlcipher released in version 1.4.3 :ticket:`5848` was
+    unfortunately non-working, in that the new ``on_connect_url`` hook was
+    erroneously not receiving a ``URL`` object under normal usage of
+    :func:`_sa.create_engine` and instead received a string that was unhandled;
+    the test suite failed to fully set up the actual conditions under which
+    this hook is called. This has been fixed.
index ff02d4dee87d779cdf20556cbbd3634aef62f293..1a9337671ed318785ac14d4030af80cecfc1bc2a 100644 (file)
@@ -9,7 +9,7 @@
 .. dialect:: sqlite+pysqlcipher
     :name: pysqlcipher
     :dbapi: sqlcipher 3 or pysqlcipher
-    :connectstring: sqlite+pysqlcipher://:passphrase/file_path[?kdf_iter=<iter>]
+    :connectstring: sqlite+pysqlcipher://:passphrase@/file_path[?kdf_iter=<iter>]
 
     Dialect for support of DBAPIs that make use of the
     `SQLCipher <https://www.zetetic.net/sqlcipher>`_ backend.
index 0351f2ebcca2d417bf79dc86485cf3b34d49f31f..3cf339cfcdca97b0a487f81676c154b757b440d0 100644 (file)
@@ -649,8 +649,7 @@ def create_engine(url, **kwargs):
     engine = engineclass(pool, dialect, u, **engine_args)
 
     if _initialize:
-
-        do_on_connect = dialect.on_connect_url(url)
+        do_on_connect = dialect.on_connect_url(u)
         if do_on_connect:
             if _wrap_do_on_connect:
                 do_on_connect = _wrap_do_on_connect(do_on_connect)
index 95dbecdc8c5b921e3afa64208987fed5bb501e0d..9285041df98e49bd236c62f4ec066e31004ffdfd 100644 (file)
@@ -596,6 +596,15 @@ class DialectTest(
                 )
             )
 
+    @testing.only_on("sqlite+pysqlcipher")
+    def test_pysqlcipher_connects(self):
+        """test #6586"""
+        str_url = str(testing.db.url)
+        e = create_engine(str_url)
+
+        with e.connect() as conn:
+            eq_(conn.scalar(text("select 1")), 1)
+
     @testing.provide_metadata
     def test_extra_reserved_words(self, connection):
         """Tests reserved words in identifiers.
index 5e8fbfb5fa6a1209c4341d3d922c334c5b392b06..ea949dfd6451344c54f545e260cce46b29b00d63 100644 (file)
@@ -485,6 +485,39 @@ class CreateEngineTest(fixtures.TestBase):
         eq_(e.dialect.foobar, 5)
         eq_(e.dialect.bathoho, False)
 
+    def test_on_connect_url(self):
+        """test #6586"""
+
+        tokens = __name__.split(".")
+
+        canary = mock.Mock()
+
+        class MyDialect(MockDialect):
+            def on_connect_url(self, url):
+                canary.on_connect_url(url)
+
+        global dialect
+        dialect = MyDialect
+        registry.register(
+            "mockdialect.ocu", ".".join(tokens[0:-1]), tokens[-1]
+        )
+
+        create_engine("mockdialect+ocu://foo:bar@host/test")
+        eq_(
+            canary.mock_calls,
+            [
+                mock.call.on_connect_url(
+                    url.URL.create(
+                        drivername="mockdialect+ocu",
+                        username="foo",
+                        password="bar",
+                        host="host",
+                        database="test",
+                    )
+                )
+            ],
+        )
+
     def test_custom(self):
         dbapi = MockDBAPI(
             foober=12, lala=18, hoho={"this": "dict"}, fooz="somevalue"