Metadata-Version: 2.1
Name: django-pgtransaction
Version: 1.0.0
Summary: A context manager/decorator which extends Django's atomic function with the ability to set isolation level and retries for a given transaction.
Home-page: https://github.com/Opus10/django-pgtransaction
License: BSD-3-Clause
Author: Opus 10 Engineering
Requires-Python: >=3.7.0,<4
Classifier: Framework :: Django
Classifier: Framework :: Django :: 2.2
Classifier: Framework :: Django :: 3.2
Classifier: Framework :: Django :: 4.0
Classifier: Framework :: Django :: 4.1
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Requires-Dist: django (>=2)
Requires-Dist: importlib_metadata (>=4); python_version >= "3.7" and python_version < "3.8"
Project-URL: Documentation, https://django-pgtransaction.readthedocs.io
Project-URL: Repository, https://github.com/Opus10/django-pgtransaction
Description-Content-Type: text/x-rst

django-pgtransaction
====================

django-pgtransaction offers a drop-in replacement for the
default ``django.db.transaction`` module which, when used on top of a PostgreSQL
database, extends the functionality of that module with Postgres-specific features.

At present, django-pgtransaction offers an extension of the
``django.db.transaction.atomic`` context manager/decorator which allows one to
dynamically set the `isolation level <https://www.postgresql.org/docs/current/transaction-iso.html>`__
when opening a transaction, as well as specifying
a retry policy for when an operation in that transaction results in a Postgres locking
exception. See the quickstart below or `the docs <https://django-pgtransaction.readthedocs.io/>`__ for examples.

Quickstart
==========

Set the isolation level of a transaction by using ``pgtransaction.atomic``:

.. code-block:: python

    import pgtransaction

    with pgtransaction.atomic(isolation_level=pgtransaction.SERIALIZABLE):
        # Do queries...

There are three isolation levels: ``pgtransaction.READ_COMMITTED``, ``pgtransaction.REPEATABLE_READ``,
and ``pgtransaction.SERIALIZABLE``. By default it inherits the parent isolation level, which is Django's
default of "READ COMMITTED".

When using stricter isolation levels like ``pgtransaction.SERIALIZABLE``, Postgres will throw
serialization errors upon concurrent updates to rows. Use the ``retry`` argument with the decorator
to retry these failures:

.. code-block:: python

    @pgtransaction.atomic(isolation_level=pgtransaction.SERIALIZABLE, retry=3)
    def do_queries():
        # Do queries...

Note that the ``retry`` argument will not work when used as a context manager. A ``RuntimeError``
will be thrown.

By default, retries are only performed when ``psycopg2.errors.SerializationError`` or
``psycopg2.errors.DeadlockDetected`` errors are raised. Configure retried psycopg2 errors with
``settings.PGTRANSACTION_RETRY_EXCEPTIONS``. You can set a default retry amount with
``settings.PGTRANSACTION_RETRY``.

``pgtransaction.atomic`` can be nested, but keep the following in mind:

1. The isolation level cannot be changed once a query has been performed.
2. The retry argument only works on the outermost invocation as a decorator, otherwise ``RuntimeError`` is raised.

Documentation
=============

Check out the `Postgres docs <https://www.postgresql.org/docs/current/transaction-iso.html>`__
to learn about transaction isolation in Postgres. 

`View the django-pgtransaction docs here
<https://django-pgtransaction.readthedocs.io/>`_.

Installation
============

Install django-pgtransaction with::

    pip3 install django-pgtransaction

After this, add ``pgtransaction`` to the ``INSTALLED_APPS``
setting of your Django project.

Contributing Guide
==================

For information on setting up django-pgtransaction for development and
contributing changes, view `CONTRIBUTING.rst <CONTRIBUTING.rst>`_.

Primary Authors
===============

- `Paul Gilmartin <https://github.com/PaulGilmartin>`__
- `Wes Kendall <https://github.com/wesleykendall>`__

