diff options
| -rw-r--r-- | doc/build/changelog/unreleased_14/sqlite_autocommit.rst | 6 | ||||
| -rw-r--r-- | lib/sqlalchemy/dialects/sqlite/base.py | 10 | ||||
| -rw-r--r-- | lib/sqlalchemy/dialects/sqlite/pysqlite.py | 6 | ||||
| -rw-r--r-- | lib/sqlalchemy/testing/requirements.py | 4 | ||||
| -rw-r--r-- | test/dialect/test_sqlite.py | 17 |
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""" |
