From bb3010380230ce63b67fc8adbaccc83951b25035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Ogam?= Date: Sun, 13 Nov 2022 13:51:32 +0100 Subject: [PATCH 1/9] Remove an unnecessary lambda in tests --- Lib/test/test_sqlite3/test_transactions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_sqlite3/test_transactions.py b/Lib/test/test_sqlite3/test_transactions.py index 5d211dd47b0b6b..d09a60248e83ca 100644 --- a/Lib/test/test_sqlite3/test_transactions.py +++ b/Lib/test/test_sqlite3/test_transactions.py @@ -325,7 +325,7 @@ def setUp(self): self.cx = sqlite.connect(":memory:") self.cx.execute("create table t(t)") self.traced = [] - self.cx.set_trace_callback(lambda stmt: self.traced.append(stmt)) + self.cx.set_trace_callback(self.traced.append) def tearDown(self): self.cx.close() From 261f21b905eb5ee9c8289255e910346d210d2f73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Ogam?= Date: Sun, 13 Nov 2022 19:30:17 +0100 Subject: [PATCH 2/9] Clarify that implicit open or roll back happens in the same method call --- Doc/library/sqlite3.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 1681fc49e9f1e0..737c751df0a2fc 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -637,24 +637,24 @@ Connection objects Commit any pending transaction to the database. If :attr:`autocommit` is ``True``, or there is no open transaction, this method does nothing. - If :attr:`!autocommit` is ``False``, a new transaction is implicitly - opened if a pending transaction was committed by this method. + If :attr:`!autocommit` is ``False``, this method implicitly opens + a new transaction after committing. .. method:: rollback() Roll back to the start of any pending transaction. If :attr:`autocommit` is ``True``, or there is no open transaction, this method does nothing. - If :attr:`!autocommit` is ``False``, a new transaction is implicitly - opened if a pending transaction was rolled back by this method. + If :attr:`!autocommit` is ``False``, this method implicitly opens + a new transaction after rolling back. .. method:: close() Close the database connection. - If :attr:`autocommit` is ``False``, - any pending transaction is implicitly rolled back. + If :attr:`autocommit` is ``False``, this method implicitly rolls back + any open transaction before closing. If :attr:`!autocommit` is ``True`` or :data:`LEGACY_TRANSACTION_CONTROL`, - no implicit transaction control is executed. + this method does not execute any implicit transaction control. Make sure to :meth:`commit` before closing to avoid losing pending changes. From d86493400519688c4603d2b7697e17102a7f4f80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Ogam?= Date: Mon, 21 Nov 2022 20:56:42 +0100 Subject: [PATCH 3/9] Add connect() to the list of implicit-transaction-opening methods --- Doc/library/sqlite3.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 737c751df0a2fc..8c0e4514bbcb3a 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -2389,11 +2389,10 @@ It is suggested to set *autocommit* to ``False``, which implies :pep:`249`-compliant transaction control. This means: -* :mod:`!sqlite3` ensures that a transaction is always open, - so :meth:`Connection.commit` and :meth:`Connection.rollback` - will implicitly open a new transaction immediately after closing - the pending one. - :mod:`!sqlite3` uses ``BEGIN DEFERRED`` statements when opening transactions. +* :meth:`Connection.connect`, :meth:`Connection.commit`, + and :meth:`Connection.rollback` implicitly open a new transaction to ensure + that a transaction is always open. + Those methods use a ``BEGIN DEFERRED`` statement when opening a transaction. * Transactions should be committed explicitly using :meth:`!commit`. * Transactions should be rolled back explicitly using :meth:`!rollback`. * An implicit rollback is performed if the database is From 8b250c05d012f375b5bf8e5bd50acb973e35e4b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Ogam?= Date: Mon, 21 Nov 2022 23:27:33 +0100 Subject: [PATCH 4/9] Recommend commit() and rollback() in legacy manual commit mode --- Doc/library/sqlite3.rst | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 8c0e4514bbcb3a..7056bb164bc505 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -2429,18 +2429,17 @@ transaction behaviour is controlled using the :attr:`Connection.isolation_level` attribute. Otherwise, :attr:`!isolation_level` has no effect. -If the connection attribute :attr:`~Connection.isolation_level` -is not ``None``, -new transactions are implicitly opened before -:meth:`~Cursor.execute` and :meth:`~Cursor.executemany` executes -``INSERT``, ``UPDATE``, ``DELETE``, or ``REPLACE`` statements; -for other statements, no implicit transaction handling is performed. -Use the :meth:`~Connection.commit` and :meth:`~Connection.rollback` methods -to respectively commit and roll back pending transactions. -You can choose the underlying `SQLite transaction behaviour`_ — -that is, whether and what type of ``BEGIN`` statements :mod:`!sqlite3` -implicitly executes – -via the :attr:`~Connection.isolation_level` attribute. +If :attr:`~Connection.isolation_level` is not ``None``: + +* :meth:`~Cursor.execute` and :meth:`~Cursor.executemany` implicitly open a new + transaction before executing an + ``INSERT``, ``UPDATE``, ``DELETE``, or ``REPLACE`` statement; + for other statements, no implicit transaction control is performed. + The type of ``BEGIN`` statement that those methods use for the underlying + `SQLite transaction behaviour`_ can be chosen via the + :attr:`~Connection.isolation_level` attribute. +* Transactions should be explicitly committed using :meth:`!commit`. +* Transactions should be explicitly rolled back using :meth:`!rollback`. If :attr:`~Connection.isolation_level` is set to ``None``, no transactions are implicitly opened at all. From d11dcfb5eb35c1239ff944051a8c0092b77d3e9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Ogam?= Date: Mon, 21 Nov 2022 23:46:59 +0100 Subject: [PATCH 5/9] Clarify PEP-249-compliant vs legacy transaction control --- Doc/library/sqlite3.rst | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 7056bb164bc505..a85ac1d650e4c9 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -1257,17 +1257,16 @@ Connection objects This attribute controls :pep:`249`-compliant transaction behaviour. :attr:`!autocommit` has three allowed values: - * ``False``: Select :pep:`249`-compliant transaction behaviour, - implying that :mod:`!sqlite3` ensures a transaction is always open. + * ``False``: :pep:`249`-compliant manual commit mode. Use :meth:`commit` and :meth:`rollback` to close transactions. This is the recommended value of :attr:`!autocommit`. - * ``True``: Use SQLite's `autocommit mode`_. + * ``True``: :pep:`249`-compliant autocommit mode. :meth:`commit` and :meth:`rollback` have no effect in this mode. * :data:`LEGACY_TRANSACTION_CONTROL`: - Pre-Python 3.12 (non-:pep:`249`-compliant) transaction control. + Legacy (pre-Python 3.12) transaction control. See :attr:`isolation_level` for more details. This is currently the default value of :attr:`!autocommit`. @@ -2385,8 +2384,8 @@ the :attr:`Connection.autocommit` attribute, which should preferrably be set using the *autocommit* parameter of :func:`connect`. -It is suggested to set *autocommit* to ``False``, -which implies :pep:`249`-compliant transaction control. +It is suggested to set *autocommit* to ``False`` to enable the +:pep:`249`-compliant manual commit mode. This means: * :meth:`Connection.connect`, :meth:`Connection.commit`, @@ -2398,16 +2397,23 @@ This means: * An implicit rollback is performed if the database is :meth:`~Connection.close`-ed with pending changes. -Set *autocommit* to ``True`` to enable SQLite's `autocommit mode`_. -In this mode, :meth:`Connection.commit` and :meth:`Connection.rollback` -have no effect. +Set *autocommit* to ``True`` to enable the :pep:`249`-compliant autocommit mode. +This means: + +* No implicit transaction control is performed. + This leaves SQLite in `autocommit mode`_, + but also allows the user to perform their own transaction control + using explicit SQL-transaction statements. +* :meth:`Connection.commit` and :meth:`Connection.rollback` have no effect. + Note that SQLite's autocommit mode is distinct from the :pep:`249`-compliant :attr:`Connection.autocommit` attribute; use :attr:`Connection.in_transaction` to query the low-level SQLite autocommit mode. -Set *autocommit* to :data:`LEGACY_TRANSACTION_CONTROL` -to leave transaction control behaviour to the +Set *autocommit* to :data:`LEGACY_TRANSACTION_CONTROL` to enable legacy +(pre-Python 3.12) transaction control. +This means transaction control behaviour is left to the :attr:`Connection.isolation_level` attribute. See :ref:`sqlite3-transaction-control-isolation-level` for more information. From 3750bf0a400142ae3ce346bd5c87cf795b688490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Ogam?= Date: Mon, 21 Nov 2022 23:56:17 +0100 Subject: [PATCH 6/9] Improve wording consistency --- Doc/library/sqlite3.rst | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index a85ac1d650e4c9..513c6144453882 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -654,7 +654,7 @@ Connection objects If :attr:`autocommit` is ``False``, this method implicitly rolls back any open transaction before closing. If :attr:`!autocommit` is ``True`` or :data:`LEGACY_TRANSACTION_CONTROL`, - this method does not execute any implicit transaction control. + this method does not perform any implicit transaction control. Make sure to :meth:`commit` before closing to avoid losing pending changes. @@ -1285,7 +1285,7 @@ Connection objects .. attribute:: in_transaction - This read-only attribute corresponds to the low-level SQLite + This read-only attribute corresponds to the low-level SQLite's `autocommit mode`_. ``True`` if a transaction is active (there are uncommitted changes), @@ -2392,10 +2392,9 @@ This means: and :meth:`Connection.rollback` implicitly open a new transaction to ensure that a transaction is always open. Those methods use a ``BEGIN DEFERRED`` statement when opening a transaction. -* Transactions should be committed explicitly using :meth:`!commit`. -* Transactions should be rolled back explicitly using :meth:`!rollback`. -* An implicit rollback is performed if the database is - :meth:`~Connection.close`-ed with pending changes. +* Transactions should be explicitly committed using :meth:`!commit`. +* Transactions should be explicitly rolled back using :meth:`!rollback`. +* :meth:`Connection.close` implicitly rolls back any open transaction. Set *autocommit* to ``True`` to enable the :pep:`249`-compliant autocommit mode. This means: @@ -2408,8 +2407,8 @@ This means: Note that SQLite's autocommit mode is distinct from the :pep:`249`-compliant :attr:`Connection.autocommit` attribute; -use :attr:`Connection.in_transaction` to query -the low-level SQLite autocommit mode. +SQLite's autocommit mode can be queried using the +:attr:`Connection.in_transaction` attribute. Set *autocommit* to :data:`LEGACY_TRANSACTION_CONTROL` to enable legacy (pre-Python 3.12) transaction control. @@ -2448,15 +2447,16 @@ If :attr:`~Connection.isolation_level` is not ``None``: * Transactions should be explicitly rolled back using :meth:`!rollback`. If :attr:`~Connection.isolation_level` is set to ``None``, -no transactions are implicitly opened at all. -This leaves the underlying SQLite library in `autocommit mode`_, -but also allows the user to perform their own transaction handling -using explicit SQL statements. -The underlying SQLite library autocommit mode can be queried using the +no implicit transaction control is performed. +This leaves SQLite in `autocommit mode`_, +but also allows the user to perform their own transaction control +using explicit SQL-transaction statements. + +SQLite's autocommit mode can be queried using the :attr:`~Connection.in_transaction` attribute. -The :meth:`~Cursor.executescript` method implicitly commits -any pending transaction before execution of the given SQL script, +:meth:`~Cursor.executescript` implicitly commits any open transaction before +executing the given SQL script, regardless of the value of :attr:`~Connection.isolation_level`. .. versionchanged:: 3.6 From b9034b184cca7fae4691766b7426ea2d7a744e1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Ogam?= Date: Sun, 13 Nov 2022 23:18:20 +0100 Subject: [PATCH 7/9] =?UTF-8?q?Remove=20two=20ambiguous=20=E2=80=98underly?= =?UTF-8?q?ing=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Doc/library/sqlite3.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 513c6144453882..e2bd2b3fbaf485 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -1299,7 +1299,7 @@ Connection objects ` of :mod:`!sqlite3`. If set to ``None``, transactions are never implicitly opened. If set to one of ``"DEFERRED"``, ``"IMMEDIATE"``, or ``"EXCLUSIVE"``, - corresponding to the underlying `SQLite transaction behaviour`_, + corresponding to the `SQLite transaction behaviour`_, :ref:`implicit transaction management ` is performed. @@ -2440,7 +2440,7 @@ If :attr:`~Connection.isolation_level` is not ``None``: transaction before executing an ``INSERT``, ``UPDATE``, ``DELETE``, or ``REPLACE`` statement; for other statements, no implicit transaction control is performed. - The type of ``BEGIN`` statement that those methods use for the underlying + The type of ``BEGIN`` statement that those methods use for the `SQLite transaction behaviour`_ can be chosen via the :attr:`~Connection.isolation_level` attribute. * Transactions should be explicitly committed using :meth:`!commit`. From 55a28c85bc733480adbf74e9b144f1637520e435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Ogam?= Date: Sun, 13 Nov 2022 19:04:38 +0100 Subject: [PATCH 8/9] =?UTF-8?q?Normalize=20=E2=80=98open=20transaction?= =?UTF-8?q?=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Doc/library/sqlite3.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index e2bd2b3fbaf485..e39331a5d647c8 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -634,7 +634,7 @@ Connection objects .. method:: commit() - Commit any pending transaction to the database. + Commit any open transaction to the database. If :attr:`autocommit` is ``True``, or there is no open transaction, this method does nothing. If :attr:`!autocommit` is ``False``, this method implicitly opens @@ -642,7 +642,7 @@ Connection objects .. method:: rollback() - Roll back to the start of any pending transaction. + Roll back to the start of any open transaction. If :attr:`autocommit` is ``True``, or there is no open transaction, this method does nothing. If :attr:`!autocommit` is ``False``, this method implicitly opens @@ -1272,7 +1272,7 @@ Connection objects This is currently the default value of :attr:`!autocommit`. Changing :attr:`!autocommit` to ``False`` will open a new transaction, - and changing it to ``True`` will commit any pending transaction. + and changing it to ``True`` will commit any open transaction. See :ref:`sqlite3-transaction-control-autocommit` for more details. @@ -1473,7 +1473,7 @@ Cursor objects Execute the SQL statements in *sql_script*. If the :attr:`~Connection.autocommit` is :data:`LEGACY_TRANSACTION_CONTROL` - and there is a pending transaction, + and there is an open transaction, an implicit ``COMMIT`` statement is executed first. No other implicit transaction control is performed; any transaction control must be added to *sql_script*. From 6db7b573c02200dce8d4d2433d0510672f6c545a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Ogam?= Date: Sun, 13 Nov 2022 23:18:01 +0100 Subject: [PATCH 9/9] =?UTF-8?q?Normalize=20=E2=80=99transaction=20control?= =?UTF-8?q?=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Doc/library/sqlite3.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index e39331a5d647c8..20d0e1ae33aa65 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -1295,7 +1295,7 @@ Connection objects .. attribute:: isolation_level - Controls the :ref:`legacy transaction handling mode + Sets the :ref:`legacy transaction control mode ` of :mod:`!sqlite3`. If set to ``None``, transactions are never implicitly opened. If set to one of ``"DEFERRED"``, ``"IMMEDIATE"``, or ``"EXCLUSIVE"``, @@ -1308,7 +1308,7 @@ Connection objects .. note:: - Using :attr:`autocommit` to control transaction handling is + Using :attr:`autocommit` to set transaction control is recommended over using :attr:`!isolation_level`. :attr:`!isolation_level` has no effect unless :attr:`autocommit` is set to :data:`LEGACY_TRANSACTION_CONTROL` (the default). @@ -1455,7 +1455,7 @@ Cursor objects against all parameter sequences or mappings found in the sequence *parameters*. It is also possible to use an :term:`iterator` yielding parameters instead of a sequence. - Uses the same implicit transaction handling as :meth:`~Cursor.execute`. + Uses the same implicit transaction control as :meth:`~Cursor.execute`. Example: