Skip to main content

Fine-grained database transaction control for Django.

Project description

Django Subatomic

Precise control over transaction logic in Django.

Splits Django's atomic into a suite of more specific utilities.

Prerequisites

This package supports sensible combinations of:

  • Python 3.12, 3.13, 3.14.
  • Django 4.2, 5.1, 5.2.

Installation

pip install django-subatomic

Usage

N.B. These docs are incomplete. More comprehensive documentation covering the usage of this library and guidance for migrating to it, will be published soon.

django-subatomic provides drop-in replacements for django.db.transaction.atomic that make behaviour more explicit and allow conditions to be expressed without side-effects.

django-subatomic does 3 things:

  • make transactional behaviour explicit;
  • express conditions without side-effects;
  • make tests more realistic.

Make transactional behaviour explicit

django.db.transaction.atomic

Django's transaction.atomic can do multiple things in several combinations:

  • open a transaction
    • optionally: error if one is already open
  • create a savepoint within a transaction
  • nothing

Some of those behaviours can be chosen with the durable and savepoint arguments. But, it is not always possible to know what it does without knowing the context in which it is being called.

django-subatomic provides utilities that can be used in place of atomic that each do a specific job:

  • transaction opens a new transaction
    • it will error if one is already open;
  • savepoint will create a savepoint
    • it will error if there is no transaction open.

django.db.transaction.on_commit

Django's on_commit also behaves differently depending on the context in which it is called. If called in a transaction, it registers a callback to be executed when the transaction commits. If called with no transaction, it executes the callback immediately.

django-subatomic provides a utility to register on-commit callbacks, which fails if there is no transaction to be committed. This makes the behaviour more obvious for a reader and interacts more reliably with testcase transactions (see "Make tests more realistic" below).

Express conditions without side-effects

Sometimes, code needs to be "atomic", i.e. it contains multiple database operations that must either all be committed, or all be rolled back. It is not possible to enforce that condition independently from managing transactions using Django's atomic. (atomic(savepoint=False) will never create a savepoint, but it might start a new transaction.)

Other times, code needs to be "durable", i.e. any changes that have been made inside it must persist (or be rolled back) once the function returns. There is no way to express this condition with Django's atomic that doesn't also open a new transaction (which is often exactly what we don't want!)

django-subatomic provides two utilities that allow these conditions to be expressed without creating transactions or savepoints:

  • transaction_required will ensure a transaction has been opened without creating a savepoint or opening the transaction itself;
  • durable will ensure a transaction is not currently open, without opening one itself.

Make tests more realistic

Tests are often wrapped in a transaction. to speed up database use. This "testcase transaction" causes Django's atomic to behave completely differently in tests than it will in regular use.

For example, if a particular call to atomic would usually always open a transaction, e.g. if it were called in a Django view handler function, in a test it would create a savepoint! If it used savepoint=False it would do nothing at all!

This causes the tests to differ significantly from real-world usage, which can lead to tests that do not test the behaviour they want to. This is particularly relevant when on-commit callbacks are involved. In the example above, on-commit callbacks registered during the transaction would usually be executed when the transaction ended in the view function. But, in a test, the transaction is never committed, so the callbacks are never executed! That means the behaviour observed in the test does not match the behaviour of the code in real life.

The utilities for managing transactions in django-subatomic emulate real-world behaviour for on-commit callbacks, ensuring the testcase transaction does not supress on-commit callbacks. That makes tests of code that use those utilities more realistic and helps to avoid bugs sneaking through automated tests.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_subatomic-0.1.1.tar.gz (11.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_subatomic-0.1.1-py3-none-any.whl (10.1 kB view details)

Uploaded Python 3

File details

Details for the file django_subatomic-0.1.1.tar.gz.

File metadata

  • Download URL: django_subatomic-0.1.1.tar.gz
  • Upload date:
  • Size: 11.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for django_subatomic-0.1.1.tar.gz
Algorithm Hash digest
SHA256 2cfdcf8542b0a789b24e6e178cc4553f492f27037f5d20d9b7f9a3aea6a755d0
MD5 54897ca85f1fd57d5e446a84c06b8407
BLAKE2b-256 8a4f26827dcbab3f80d795804f4793531f256b5d856457f5fb76ec36e6c54aed

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_subatomic-0.1.1.tar.gz:

Publisher: build_and_publish.yaml on kraken-tech/django-subatomic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_subatomic-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for django_subatomic-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5afc367fe6df2a809603d83ac269b098731dcd25cad3d54228ed7b3aa2cd58fd
MD5 f02eafe96d0402c9c7bfee6c1be5cdaa
BLAKE2b-256 1cd728ee8fd10696e5aae6257bebc8aad567dc6a54e41da1b2222dcfc516af63

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_subatomic-0.1.1-py3-none-any.whl:

Publisher: build_and_publish.yaml on kraken-tech/django-subatomic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page