Skip to content

Commit 30684a5

Browse files
committed
raising an exception with nested transactions
1 parent 72eb453 commit 30684a5

File tree

4 files changed

+34
-2
lines changed

4 files changed

+34
-2
lines changed

piccolo/engine/exceptions.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
class TransactionError(Exception):
2+
pass

piccolo/engine/postgres.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from asyncpg.pool import Pool
1313

1414
from piccolo.engine.base import Batch, Engine
15+
from piccolo.engine.exceptions import TransactionError
1516
from piccolo.query.base import Query
1617
from piccolo.querystring import QueryString
1718
from piccolo.utils.sync import run_sync
@@ -150,6 +151,11 @@ class Transaction:
150151

151152
def __init__(self, engine: PostgresEngine):
152153
self.engine = engine
154+
if self.engine.transaction_connection.get():
155+
raise TransactionError(
156+
"A transaction is already active - nested transactions aren't "
157+
"currently supported."
158+
)
153159

154160
async def __aenter__(self):
155161
if self.engine.pool:

piccolo/engine/sqlite.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from aiosqlite import Cursor, Connection
1010

1111
from piccolo.engine.base import Batch, Engine
12+
from piccolo.engine.exceptions import TransactionError
1213
from piccolo.query.base import Query
1314
from piccolo.querystring import QueryString
1415
from piccolo.utils.sync import run_sync
@@ -126,6 +127,11 @@ class Transaction:
126127

127128
def __init__(self, engine: SQLiteEngine):
128129
self.engine = engine
130+
if self.engine.transaction_connection.get():
131+
raise TransactionError(
132+
"A transaction is already active - nested transactions aren't "
133+
"currently supported."
134+
)
129135

130136
async def __aenter__(self):
131137
self.connection = await self.engine.get_connection()

tests/engine/test_nested_transaction.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
from unittest import TestCase
33

44
from piccolo.columns.column_types import Varchar
5+
from piccolo.engine.exceptions import TransactionError
56
from piccolo.engine.sqlite import SQLiteEngine
67
from piccolo.table import Table
78

8-
from ..base import sqlite_only
9+
from ..base import sqlite_only, DBTestCase
10+
from ..example_project.tables import Manager
911

1012

1113
ENGINE_1 = SQLiteEngine(path="engine1.sqlite")
@@ -21,7 +23,7 @@ class Roadie(Table, db=ENGINE_2):
2123

2224

2325
@sqlite_only
24-
class TestNestedTransaction(TestCase):
26+
class TestDifferentDB(TestCase):
2527
def setUp(self):
2628
ENGINE_1.remove_db_file()
2729
ENGINE_2.remove_db_file()
@@ -53,3 +55,19 @@ async def run_nested(self):
5355

5456
def test_nested(self):
5557
asyncio.run(self.run_nested())
58+
59+
60+
class TestSameDB(DBTestCase):
61+
async def run_nested(self):
62+
"""
63+
Nested transactions currently aren't permitted in a connection.
64+
"""
65+
with self.assertRaises(TransactionError):
66+
async with Manager._meta.db.transaction():
67+
await Manager(name="Bob").save().run()
68+
69+
async with Manager._meta.db.transaction():
70+
await Manager(name="Dave").save().run()
71+
72+
def test_nested(self):
73+
asyncio.run(self.run_nested())

0 commit comments

Comments
 (0)