Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d35251d

Browse files
committed
#8845: expose sqlite3 inTransaction as RO in_transaction Connection attribute.
Patch by R. David Murray, unit tests by Shashwat Anand.
1 parent bcb8d3a commit d35251d

6 files changed

Lines changed: 50 additions & 1 deletion

File tree

Doc/library/sqlite3.rst

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,13 @@ Connection Objects
227227
one of "DEFERRED", "IMMEDIATE" or "EXCLUSIVE". See section
228228
:ref:`sqlite3-controlling-transactions` for a more detailed explanation.
229229

230+
.. attribute:: Connection.in_transaction
231+
232+
.. versionadded:: 3.2
233+
234+
:cont:`True` if a transaction is active (there are uncommitted changes),
235+
:const:`False` otherwise. Read-only attribute.
236+
230237

231238
.. method:: Connection.cursor([cursorClass])
232239

@@ -806,7 +813,8 @@ So if you are within a transaction and issue a command like ``CREATE TABLE
806813
before executing that command. There are two reasons for doing that. The first
807814
is that some of these commands don't work within transactions. The other reason
808815
is that sqlite3 needs to keep track of the transaction state (if a transaction
809-
is active or not).
816+
is active or not). The current transaction state is exposed through the
817+
:attr:`Connection.in_transaction` attribute of the connection object.
810818

811819
You can control which kind of ``BEGIN`` statements sqlite3 implicitly executes
812820
(or none at all) via the *isolation_level* parameter to the :func:`connect`

Doc/whatsnew/3.2.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,18 @@ New, Improved, and Deprecated Modules
100100

101101
(Contributed by Tarek Ziade.)
102102

103+
* The *sqlite3* module has some new features:
104+
105+
* XXX *enable_load_extension*
106+
107+
* XXX *load_extension*
108+
109+
* New :class:`~sqlite3.Connection` attribute
110+
:attr:`~sqlite3.Connection.in_transaction` is :const:`True` when there
111+
are uncommitted changes, and :const:`False` otherwise. (Contributed
112+
by R. David Murray and Shashwat Anand, :issue:`8845`.)
113+
114+
103115
Multi-threading
104116
===============
105117

Lib/sqlite3/test/dbapi.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ def CheckNotSupportedError(self):
8484
"NotSupportedError is not a subclass of DatabaseError")
8585

8686
class ConnectionTests(unittest.TestCase):
87+
8788
def setUp(self):
8889
self.cx = sqlite.connect(":memory:")
8990
cu = self.cx.cursor()
@@ -140,6 +141,28 @@ def CheckExceptions(self):
140141
self.assertEqual(self.cx.ProgrammingError, sqlite.ProgrammingError)
141142
self.assertEqual(self.cx.NotSupportedError, sqlite.NotSupportedError)
142143

144+
def CheckInTransaction(self):
145+
# Can't use db from setUp because we want to test initial state.
146+
cx = sqlite.connect(":memory:")
147+
cu = cx.cursor()
148+
self.assertEqual(cx.in_transaction, False)
149+
cu.execute("create table transactiontest(id integer primary key, name text)")
150+
self.assertEqual(cx.in_transaction, False)
151+
cu.execute("insert into transactiontest(name) values (?)", ("foo",))
152+
self.assertEqual(cx.in_transaction, True)
153+
cu.execute("select name from transactiontest where name=?", ["foo"])
154+
row = cu.fetchone()
155+
self.assertEqual(cx.in_transaction, True)
156+
cx.commit()
157+
self.assertEqual(cx.in_transaction, False)
158+
cu.execute("select name from transactiontest where name=?", ["foo"])
159+
row = cu.fetchone()
160+
self.assertEqual(cx.in_transaction, False)
161+
162+
def CheckInTransactionRO(self):
163+
with self.assertRaises(AttributeError):
164+
self.cx.in_transaction = True
165+
143166
class CursorTests(unittest.TestCase):
144167
def setUp(self):
145168
self.cx = sqlite.connect(":memory:")

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Billy G. Allie
1919
Kevin Altis
2020
Joe Amenta
2121
Mark Anacker
22+
Shashwat Anand
2223
Anders Andersen
2324
John Anderson
2425
Erik Andersén

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,9 @@ C-API
398398
Library
399399
-------
400400

401+
- Issue #8845: sqlite3 Connection objects now have a read-only in_transaction
402+
attribute that is True iff there are uncommitted changes.
403+
401404
- Issue #1289118: datetime.timedelta objects can now be multiplied by float
402405
and divided by float and int objects. Results are rounded to the nearest
403406
multiple of timedelta.resolution with ties resolved using round-half-to-even

Modules/_sqlite/connection.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include "cache.h"
2525
#include "module.h"
26+
#include "structmember.h"
2627
#include "connection.h"
2728
#include "statement.h"
2829
#include "cursor.h"
@@ -1551,6 +1552,7 @@ static struct PyMemberDef connection_members[] =
15511552
{"NotSupportedError", T_OBJECT, offsetof(pysqlite_Connection, NotSupportedError), READONLY},
15521553
{"row_factory", T_OBJECT, offsetof(pysqlite_Connection, row_factory)},
15531554
{"text_factory", T_OBJECT, offsetof(pysqlite_Connection, text_factory)},
1555+
{"in_transaction", T_BOOL, offsetof(pysqlite_Connection, inTransaction), READONLY},
15541556
{NULL}
15551557
};
15561558

0 commit comments

Comments
 (0)