summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/build/changelog/unreleased_14/sqlite_autocommit.rst6
-rw-r--r--lib/sqlalchemy/dialects/sqlite/base.py10
-rw-r--r--lib/sqlalchemy/dialects/sqlite/pysqlite.py6
-rw-r--r--lib/sqlalchemy/testing/requirements.py4
-rw-r--r--test/dialect/test_sqlite.py17
5 files changed, 41 insertions, 2 deletions
diff --git a/doc/build/changelog/unreleased_14/sqlite_autocommit.rst b/doc/build/changelog/unreleased_14/sqlite_autocommit.rst
new file mode 100644
index 000000000..183e0eeed
--- /dev/null
+++ b/doc/build/changelog/unreleased_14/sqlite_autocommit.rst
@@ -0,0 +1,6 @@
+.. change::
+ :tags: bug, sqlite
+
+ Fixed bug where the error message for SQLite invalid isolation level on the
+ pysqlite driver would fail to indicate that "AUTOCOMMIT" is one of the
+ valid isolation levels.
diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py
index dc5ebc3f0..c4a6bf8e9 100644
--- a/lib/sqlalchemy/dialects/sqlite/base.py
+++ b/lib/sqlalchemy/dialects/sqlite/base.py
@@ -1915,7 +1915,9 @@ class SQLiteDialect(default.DefaultDialect):
14,
)
- _isolation_lookup = {"READ UNCOMMITTED": 1, "SERIALIZABLE": 0}
+ _isolation_lookup = util.immutabledict(
+ {"READ UNCOMMITTED": 1, "SERIALIZABLE": 0}
+ )
def set_isolation_level(self, connection, level):
try:
@@ -1925,7 +1927,11 @@ class SQLiteDialect(default.DefaultDialect):
exc.ArgumentError(
"Invalid value '%s' for isolation_level. "
"Valid isolation levels for %s are %s"
- % (level, self.name, ", ".join(self._isolation_lookup))
+ % (
+ level,
+ self.name,
+ ", ".join(self._isolation_lookup),
+ )
),
replace_context=err,
)
diff --git a/lib/sqlalchemy/dialects/sqlite/pysqlite.py b/lib/sqlalchemy/dialects/sqlite/pysqlite.py
index 96a5351da..0f96e8830 100644
--- a/lib/sqlalchemy/dialects/sqlite/pysqlite.py
+++ b/lib/sqlalchemy/dialects/sqlite/pysqlite.py
@@ -492,6 +492,12 @@ class SQLiteDialect_pysqlite(SQLiteDialect):
def _get_server_version_info(self, connection):
return self.dbapi.sqlite_version_info
+ _isolation_lookup = SQLiteDialect._isolation_lookup.union(
+ {
+ "AUTOCOMMIT": None,
+ }
+ )
+
def set_isolation_level(self, connection, level):
if hasattr(connection, "connection"):
dbapi_connection = connection.connection
diff --git a/lib/sqlalchemy/testing/requirements.py b/lib/sqlalchemy/testing/requirements.py
index 742a9a1f8..e6e5db774 100644
--- a/lib/sqlalchemy/testing/requirements.py
+++ b/lib/sqlalchemy/testing/requirements.py
@@ -1227,6 +1227,10 @@ class SuiteRequirements(Requirements):
return self.python36
@property
+ def insert_order_dicts(self):
+ return self.python37
+
+ @property
def python36(self):
return exclusions.skip_if(
lambda: sys.version_info < (3, 6),
diff --git a/test/dialect/test_sqlite.py b/test/dialect/test_sqlite.py
index b5ce291eb..ed0f11907 100644
--- a/test/dialect/test_sqlite.py
+++ b/test/dialect/test_sqlite.py
@@ -54,6 +54,7 @@ from sqlalchemy.testing import expect_warnings
from sqlalchemy.testing import fixtures
from sqlalchemy.testing import is_
from sqlalchemy.testing import mock
+from sqlalchemy.testing.assertions import expect_raises_message
from sqlalchemy.types import Boolean
from sqlalchemy.types import Date
from sqlalchemy.types import DateTime
@@ -596,6 +597,22 @@ class DialectTest(
)
)
+ @testing.requires.insert_order_dicts
+ @testing.only_on("sqlite+pysqlite")
+ def test_isolation_level_message(self):
+ # needs to test that all three words are present and we also
+ # dont want to default all isolation level messages to use
+ # sorted(), so rely on python 3.7 for ordering of keywords
+ # in the message
+ with expect_raises_message(
+ exc.ArgumentError,
+ "Invalid value 'invalid' for "
+ "isolation_level. Valid isolation levels for "
+ "sqlite are READ UNCOMMITTED, SERIALIZABLE, AUTOCOMMIT",
+ ):
+ with testing.db.connect() as conn:
+ conn.execution_options(isolation_level="invalid")
+
@testing.only_on("sqlite+pysqlcipher")
def test_pysqlcipher_connects(self):
"""test #6586"""