]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- documenation updates to clarify specific SQLite versions
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 21 Jan 2016 20:21:33 +0000 (15:21 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 21 Jan 2016 20:31:37 +0000 (15:31 -0500)
that have problems with right-nested joins and UNION column keys;
references #3633 references #3634.   backport from 1.1 to 0.9
announcing 1.1 as where these behaviors will be retired based
on version-specific checks
- fix test_resultset so that it passes when SQLite 3.10.0 is
present, references #3633

(cherry picked from commit 89fa08792e98b9e31452aa3c949d9b909b10e7cd)

doc/build/changelog/migration_09.rst
lib/sqlalchemy/dialects/sqlite/base.py
test/sql/test_query.py

index b07aed925547b9c87e67bfded6bc8f04403fe342..913815794f79b6bb4d530561d3a93931e8aa8c20 100644 (file)
@@ -1125,7 +1125,7 @@ as INNER JOINs could always be flattened)::
 
     SELECT a.*, b.*, c.* FROM a LEFT OUTER JOIN (b JOIN c ON b.id = c.id) ON a.id
 
-This was due to the fact that SQLite, even today, cannot parse a statement of the above format::
+This was due to the fact that SQLite up until version **3.7.16** cannot parse a statement of the above format::
 
     SQLite version 3.7.15.2 2013-01-09 11:53:05
     Enter ".help" for instructions
@@ -1248,6 +1248,12 @@ with the above queries rewritten as::
         JOIN item ON item.id = order_item_1.item_id AND item.type IN (?)
     ) AS anon_1 ON "order".id = anon_1.order_item_1_order_id
 
+.. note::
+
+    As of SQLAlchemy 1.1, the workarounds present in this feature for SQLite
+    will automatically disable themselves when SQLite version **3.7.16**
+    or greater is detected, as SQLite has repaired support for right-nested joins.
+
 The :meth:`.Join.alias`, :func:`.aliased` and :func:`.with_polymorphic` functions now
 support a new argument, ``flat=True``, which is used to construct aliases of joined-table
 entities without embedding into a SELECT.   This flag is not on by default, to help with
index fc36491000a6b3f61763365da30686a41295d7fd..5a5ed0bc28573dc5bb8cb05739ba3bce6908b84e 100644 (file)
@@ -331,8 +331,14 @@ Dotted Column Names
 Using table or column names that explicitly have periods in them is
 **not recommended**.   While this is generally a bad idea for relational
 databases in general, as the dot is a syntactically significant character,
-the SQLite driver has a bug which requires that SQLAlchemy filter out these
-dots in result sets.
+the SQLite driver up until version **3.10.0** of SQLite has a bug which
+requires that SQLAlchemy filter out these dots in result sets.
+
+.. note::
+
+    The following SQLite issue has been resolved as of version 3.10.0
+    of SQLite.  SQLAlchemy as of **1.1** automatically disables its internal
+    workarounds based on detection of this version.
 
 The bug, entirely outside of SQLAlchemy, can be illustrated thusly::
 
@@ -907,6 +913,9 @@ class SQLiteExecutionContext(default.DefaultExecutionContext):
         return self.execution_options.get("sqlite_raw_colnames", False)
 
     def _translate_colname(self, colname):
+        # TODO: detect SQLite version 3.10.0 or greater;
+        # see [ticket:3633]
+
         # adjust for dotted column names.  SQLite
         # in the case of UNION may store col names as
         # "tablename.colname", or if using an attached database,
@@ -926,6 +935,9 @@ class SQLiteDialect(default.DefaultDialect):
     supports_empty_insert = False
     supports_cast = True
     supports_multivalues_insert = True
+
+    # TODO: detect version 3.7.16 or greater;
+    # see [ticket:3634]
     supports_right_nested_joins = False
 
     default_paramstyle = 'qmark'
index 43afb131b1aec34f280012b2906268db6f9a8040..d9dfba6f9f5c17e7e8d29723a9a3c2bbb3eb21c3 100644 (file)
@@ -871,7 +871,6 @@ class QueryTest(fixtures.TestBase):
         eq_(r['user_name'], "john")
         eq_(list(r.keys()), ["user_id", "user_name"])
 
-    @testing.only_on("sqlite", "sqlite specific feature")
     def test_column_accessor_sqlite_raw(self):
         users.insert().execute(
             dict(user_id=1, user_name='john'),
@@ -884,13 +883,24 @@ class QueryTest(fixtures.TestBase):
             "query_users.user_name from query_users",
             bind=testing.db).execution_options(sqlite_raw_colnames=True). \
             execute().first()
-        assert 'user_id' not in r
-        assert 'user_name' not in r
-        eq_(r['query_users.user_id'], 1)
-        eq_(r['query_users.user_name'], "john")
-        eq_(list(r.keys()), ["query_users.user_id", "query_users.user_name"])
 
-    @testing.only_on("sqlite", "sqlite specific feature")
+        if testing.against("sqlite < 3.10.0"):
+            assert 'user_id' not in r
+            assert 'user_name' not in r
+            eq_(r['query_users.user_id'], 1)
+            eq_(r['query_users.user_name'], "john")
+
+            eq_(
+                list(r.keys()),
+                ["query_users.user_id", "query_users.user_name"])
+        else:
+            assert 'query_users.user_id' not in r
+            assert 'query_users.user_name' not in r
+            eq_(r['user_id'], 1)
+            eq_(r['user_name'], "john")
+
+            eq_(list(r.keys()), ["user_id", "user_name"])
+
     def test_column_accessor_sqlite_translated(self):
         users.insert().execute(
             dict(user_id=1, user_name='john'),
@@ -904,8 +914,13 @@ class QueryTest(fixtures.TestBase):
             bind=testing.db).execute().first()
         eq_(r['user_id'], 1)
         eq_(r['user_name'], "john")
-        eq_(r['query_users.user_id'], 1)
-        eq_(r['query_users.user_name'], "john")
+
+        if testing.against("sqlite < 3.10.0"):
+            eq_(r['query_users.user_id'], 1)
+            eq_(r['query_users.user_name'], "john")
+        else:
+            assert 'query_users.user_id' not in r
+            assert 'query_users.user_name'not in r
         eq_(list(r.keys()), ["user_id", "user_name"])
 
     def test_column_accessor_labels_w_dots(self):