@@ -185,7 +185,7 @@
Loading
185 185
            return connection
186 186
187 187
    def transaction(self, *, force_rollback: bool = False) -> "Transaction":
188 -
        return self.connection().transaction(force_rollback=force_rollback)
188 +
        return Transaction(self.connection, force_rollback=force_rollback)
189 189
190 190
    @contextlib.contextmanager
191 191
    def force_rollback(self) -> typing.Iterator[None]:
@@ -275,7 +275,10 @@
Loading
275 275
                    yield record
276 276
277 277
    def transaction(self, *, force_rollback: bool = False) -> "Transaction":
278 -
        return Transaction(self, force_rollback)
278 +
        def connection_callable() -> Connection:
279 +
            return self
280 +
281 +
        return Transaction(connection_callable, force_rollback)
279 282
280 283
    @property
281 284
    def raw_connection(self) -> typing.Any:
@@ -296,10 +299,13 @@
Loading
296 299
297 300
298 301
class Transaction:
299 -
    def __init__(self, connection: Connection, force_rollback: bool) -> None:
300 -
        self._connection = connection
302 +
    def __init__(
303 +
        self,
304 +
        connection_callable: typing.Callable[[], Connection],
305 +
        force_rollback: bool,
306 +
    ) -> None:
307 +
        self._connection_callable = connection_callable
301 308
        self._force_rollback = force_rollback
302 -
        self._transaction = connection._connection.transaction()
303 309
304 310
    async def __aenter__(self) -> "Transaction":
305 311
        """
@@ -341,6 +347,9 @@
Loading
341 347
        return wrapper
342 348
343 349
    async def start(self) -> "Transaction":
350 +
        self._connection = self._connection_callable()
351 +
        self._transaction = self._connection._connection.transaction()
352 +
344 353
        async with self._connection._transaction_lock:
345 354
            is_root = not self._connection._transaction_stack
346 355
            await self._connection.__aenter__()

@@ -1,4 +1,4 @@
Loading
1 1
from databases.core import Database, DatabaseURL
2 2
3 -
__version__ = "0.3.0"
3 +
__version__ = "0.3.1"
4 4
__all__ = ["Database", "DatabaseURL"]

@@ -451,15 +451,16 @@
Loading
451 451
    """
452 452
    Ensure that @database.transaction() is supported.
453 453
    """
454 -
    async with Database(database_url, force_rollback=True) as database:
454 +
    database = Database(database_url, force_rollback=True)
455 455
456 -
        @database.transaction()
457 -
        async def insert_data(raise_exception):
458 -
            query = notes.insert().values(text="example", completed=True)
459 -
            await database.execute(query)
460 -
            if raise_exception:
461 -
                raise RuntimeError()
456 +
    @database.transaction()
457 +
    async def insert_data(raise_exception):
458 +
        query = notes.insert().values(text="example", completed=True)
459 +
        await database.execute(query)
460 +
        if raise_exception:
461 +
            raise RuntimeError()
462 462
463 +
    async with database:
463 464
        with pytest.raises(RuntimeError):
464 465
            await insert_data(raise_exception=True)
465 466
Files Coverage
databases 100.00%
tests 100.00%
Project Totals (14 files) 100.00%
399.1
TRAVIS_PYTHON_VERSION=3.6
TRAVIS_OS_NAME=linux
399.2
TRAVIS_PYTHON_VERSION=3.7
TRAVIS_OS_NAME=linux
400.1
TRAVIS_PYTHON_VERSION=3.6
TRAVIS_OS_NAME=linux
400.2
TRAVIS_PYTHON_VERSION=3.7
TRAVIS_OS_NAME=linux
1
coverage:
2
  precision: 2
3
  round: down
4
  range: "80...100"
5

6
  status:
7
    project: yes
8
    patch: no
9
    changes: no
10

11
comment: off
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading