]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- changelog and docs for #3332, fixes #3332
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 15 Mar 2016 21:11:08 +0000 (17:11 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 15 Mar 2016 21:17:21 +0000 (17:17 -0400)
- make docs for isolation level more consistent between postgresql
and mysql
- move mysql autocommit tests

doc/build/changelog/changelog_11.rst
doc/build/changelog/migration_11.rst
lib/sqlalchemy/dialects/mysql/base.py
lib/sqlalchemy/dialects/postgresql/base.py
test/dialect/mysql/test_dialect.py

index ef52c4bbef7447b2af77f40979a2905609a0c3aa..e6dac926570f5676bcca5c4d79f3de3976ba2a58 100644 (file)
 .. changelog::
     :version: 1.1.0b1
 
+    .. change::
+        :tags: feature, mysql
+        :tickets: 3332
+
+        Added support for "autocommit" on MySQL drivers, via the
+        AUTOCOMMIT isolation level setting.  Pull request courtesy
+        Roman Podoliaka.
+
+        .. seealso::
+
+            :ref:`change_3332`
+
     .. change::
         :tags: bug, orm
         :tickets: 3677
index cbf213d440d7c4108ed7a5932a9910eb621b9b87..3f40c7278bee4bbbcad7f68695f88a7e99c326bc 100644 (file)
@@ -1861,6 +1861,25 @@ common to both MySQL and Postgresql.
 
 :ticket:`3547`
 
+.. _change_3332:
+
+Added support for AUTOCOMMIT "isolation level"
+----------------------------------------------
+
+The MySQL dialect now accepts the value "AUTOCOMMIT" for the
+:paramref:`.create_engine.isolation_level` and
+:paramref:`.Connection.execution_options.isolation_level`
+parameters::
+
+    connection = engine.connect()
+    connection = connection.execution_options(
+        isolation_level="AUTOCOMMIT"
+    )
+
+The isolation level makes use of the various "autocommit" attributes
+provided by most MySQL DBAPIs.
+
+:ticket:`3332`
 
 .. _change_mysql_3216:
 
index b04070162328b5f905f9561a24bb320603107cb1..b85e32db0142aed1984d518788072a71eaf79e6e 100644 (file)
@@ -111,19 +111,45 @@ to be used.
 Transaction Isolation Level
 ---------------------------
 
-:func:`.create_engine` accepts an :paramref:`.create_engine.isolation_level`
-parameter which results in the command ``SET SESSION
-TRANSACTION ISOLATION LEVEL <level>`` being invoked for
-every new connection. Valid values for this parameter are
-``READ COMMITTED``, ``READ UNCOMMITTED``,
-``REPEATABLE READ``, and ``SERIALIZABLE``::
+All MySQL dialects support setting of transaction isolation level
+both via a dialect-specific parameter :paramref:`.create_engine.isolation_level`
+accepted by :func:`.create_engine`,
+as well as the :paramref:`.Connection.execution_options.isolation_level`
+argument as passed to :meth:`.Connection.execution_options`.
+This feature works by issuing the command
+``SET SESSION TRANSACTION ISOLATION LEVEL <level>`` for
+each new connection.  For the special AUTOCOMMIT isolation level, DBAPI-specific
+techniques are used.
+
+To set isolation level using :func:`.create_engine`::
 
     engine = create_engine(
                     "mysql://scott:tiger@localhost/test",
                     isolation_level="READ UNCOMMITTED"
                 )
 
-.. versionadded:: 0.7.6
+To set using per-connection execution options::
+
+    connection = engine.connect()
+    connection = connection.execution_options(
+        isolation_level="READ COMMITTED"
+    )
+
+Valid values for ``isolation_level`` include:
+
+* ``READ COMMITTED``
+* ``READ UNCOMMITTED``
+* ``REPEATABLE READ``
+* ``SERIALIZABLE``
+* ``AUTOCOMMIT``
+
+The special ``AUTOCOMMIT`` value makes use of the various "autocommit"
+attributes provided by specific DBAPIs, and is currently supported by
+MySQLdb, MySQL-Client, MySQL-Connector Python, and PyMySQL.   Using it,
+the MySQL connection will return true for the value of
+``SELECT @@autocommit;``.
+
+.. versionadded:: 1.1 - added support for the AUTOCOMMIT isolation level.
 
 AUTO_INCREMENT Behavior
 -----------------------
@@ -1439,6 +1465,8 @@ class MySQLDialect(default.DefaultDialect):
         level = level.replace('_', ' ')
 
         # adjust for ConnectionFairy being present
+        # allows attribute set e.g. "connection.autocommit = True"
+        # to work properly
         if hasattr(connection, 'connection'):
             connection = connection.connection
 
index b16a82e043c015845dcb50d7ccedd99062639673..c0a3708d4acb865aa5b2d4c7907197368f8a71aa 100644 (file)
@@ -50,11 +50,12 @@ Transaction Isolation Level
 All Postgresql dialects support setting of transaction isolation level
 both via a dialect-specific parameter :paramref:`.create_engine.isolation_level`
 accepted by :func:`.create_engine`,
-as well as the ``isolation_level`` argument as passed to
+as well as the :paramref:`.Connection.execution_options.isolation_level` argument as passed to
 :meth:`.Connection.execution_options`.  When using a non-psycopg2 dialect,
 this feature works by issuing the command
 ``SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL <level>`` for
-each new connection.
+each new connection.  For the special AUTOCOMMIT isolation level, DBAPI-specific
+techniques are used.
 
 To set isolation level using :func:`.create_engine`::
 
@@ -76,10 +77,7 @@ Valid values for ``isolation_level`` include:
 * ``READ UNCOMMITTED``
 * ``REPEATABLE READ``
 * ``SERIALIZABLE``
-
-The :mod:`~sqlalchemy.dialects.postgresql.psycopg2` and
-:mod:`~sqlalchemy.dialects.postgresql.pg8000` dialects also offer the
-special level ``AUTOCOMMIT``.
+* ``AUTOCOMMIT`` - on psycopg2 / pg8000 only
 
 .. seealso::
 
index 1288b50d7b18ab0ee1d500f6d1766566f7d12abc..ab719b36812d5906b05cc8ae142e3ea625c54c77 100644 (file)
@@ -11,6 +11,7 @@ import datetime
 
 class DialectTest(fixtures.TestBase):
     __backend__ = True
+    __only_on__ = 'mysql'
 
     def test_ssl_arguments_mysqldb(self):
         from sqlalchemy.dialects.mysql import mysqldb
@@ -97,6 +98,29 @@ class DialectTest(fixtures.TestBase):
             conn = eng.connect()
             eq_(conn.dialect._connection_charset, enc)
 
+    def test_autocommit_isolation_level(self):
+        c = testing.db.connect().execution_options(
+            isolation_level='AUTOCOMMIT'
+        )
+        assert c.execute('SELECT @@autocommit;').scalar()
+
+        c = c.execution_options(isolation_level='READ COMMITTED')
+        assert not c.execute('SELECT @@autocommit;').scalar()
+
+    def test_isolation_level(self):
+        values = {
+            # sqlalchemy -> mysql
+            'READ UNCOMMITTED': 'READ-UNCOMMITTED',
+            'READ COMMITTED': 'READ-COMMITTED',
+            'REPEATABLE READ': 'REPEATABLE-READ',
+            'SERIALIZABLE': 'SERIALIZABLE'
+        }
+        for sa_value, mysql_value in values.items():
+            c = testing.db.connect().execution_options(
+                isolation_level=sa_value
+            )
+            assert c.execute('SELECT @@tx_isolation;').scalar() == mysql_value
+
 class SQLModeDetectionTest(fixtures.TestBase):
     __only_on__ = 'mysql'
     __backend__ = True
@@ -163,26 +187,3 @@ class ExecutionTest(fixtures.TestBase):
         d = testing.db.scalar(func.sysdate())
         assert isinstance(d, datetime.datetime)
 
-    @testing.only_on(['mysql+mysqldb',
-                      'mysql+mysqlconnector',
-                      'mysql+pymysql',
-                      'mysql+cymysql'])
-    def test_autocommit_isolation_level(self):
-        c = testing.db.connect().execution_options(
-            isolation_level='AUTOCOMMIT'
-        )
-        assert c.execute('SELECT @@autocommit;').scalar()
-
-    def test_isolation_level(self):
-        values = {
-            # sqlalchemy -> mysql
-            'READ UNCOMMITTED': 'READ-UNCOMMITTED',
-            'READ COMMITTED': 'READ-COMMITTED',
-            'REPEATABLE READ': 'REPEATABLE-READ',
-            'SERIALIZABLE': 'SERIALIZABLE'
-        }
-        for sa_value, mysql_value in values.items():
-            c = testing.db.connect().execution_options(
-                isolation_level=sa_value
-            )
-            assert c.execute('SELECT @@tx_isolation;').scalar() == mysql_value