django-pgware
PostgreSQL utilities for Django: advisory locks, GUC management, and logging suppression.
What it is
A small, dependency-light toolkit of three independent PostgreSQL utilities for Django. Each is a context manager (and, where it makes sense, a decorator) that borrows Django's database connection, performs a session-scoped action, and reliably undoes it on exit: advisory locks (sync + async), GUC setting (pg_set / atomic_set), and logging suppression (hush, for keeping sensitive query parameters out of the logs).
See ARCHITECTURE.md for the internals and invariants, and THEORY.md for the design rationale.
Status
Beta (1.0.x). The public API is stable; see CHANGELOG.md for recent changes.
Installation
pip install django-pgware
You'll also need a PostgreSQL database adapter — either psycopg2 or psycopg (v3):
pip install django-pgware[psycopg2]
# or
pip install django-pgware[psycopg3]
Advisory Locks
Context managers for PostgreSQL advisory locks — synchronous and asynchronous.
from django_pg_utils import advisory_lock
# Exclusive lock (blocks until acquired):
with advisory_lock("my-task") as acquired:
assert acquired is True
do_exclusive_work()
# Shared lock:
with advisory_lock("my-task", shared=True):
do_shared_work()
# Non-blocking:
with advisory_lock("my-task", wait=False) as acquired:
if acquired:
do_work()
Async
from django_pg_utils import async_advisory_lock
async with async_advisory_lock("my-task") as acquired:
await do_work()
Lock ID Types
| Type | Example | Notes |
|---|---|---|
str |
"my-lock" |
Hashed to 64-bit via SHA-256 |
int |
12345 |
Used directly as bigint |
tuple[int, int] |
(5, 9) |
Two-argument advisory lock |
Parameters
| Parameter | Default | Description |
|---|---|---|
lock_id |
required | String, int, or (int, int) tuple |
shared |
False |
Shared lock (vs exclusive) |
wait |
True |
Block until acquired |
comment |
None |
Toggle the auto-generated file:line SQL comment. If None, resolves to settings.ADVISORY_LOCK_COMMENT if set, else settings.DEBUG |
using |
None |
Django database alias |
GUC Management
Temporarily SET PostgreSQL GUCs within a scope, with automatic cleanup.
pg_set — session-level SET / RESET
from django_pg_utils import pg_set
with pg_set("work_mem", "256MB"):
MyModel.objects.complex_query()
# Multiple GUCs:
with pg_set([("work_mem", "256MB"), ("statement_timeout", "30s")]):
...
# As a decorator:
@pg_set("work_mem", "256MB")
def my_view(request):
...
atomic_set — transaction-level SET LOCAL
from django_pg_utils import atomic_set
with atomic_set("work_mem", "256MB"):
MyModel.objects.complex_query()
Wraps the scope in atomic() and uses SET LOCAL — settings revert automatically when the transaction ends.
When to use which
pg_set |
atomic_set |
|
|---|---|---|
| Mechanism | SET / RESET |
SET LOCAL inside atomic() |
| Scope | Session (connection) | Transaction |
| Cleanup | Explicit RESET on exit |
Automatic on COMMIT / ROLLBACK |
Logging Suppression (hush)
Suppress PostgreSQL server logging and Django query logging within a scope — useful for protecting sensitive data (PCI cardholder data, credentials, tokens).
from django_pg_utils import hush
# Context manager:
with hush() as result:
cursor.execute("SELECT decrypt_card(%s)", [card_token])
# Decorator:
@hush
def process_payment(card_token):
...
# Parameterized:
@hush(strict=True, database="payments")
def process_payment(card_token):
...
Parameters
| Parameter | Default | Description |
|---|---|---|
database |
default connection | Django database alias. Pass "*" to suppress on every configured connection |
settings |
all 5 defaults | List of PG setting names to suppress |
strict |
False |
Raise HushError if suppression incomplete |
hush()targets only the default connection unless you pass an explicit alias ordatabase="*". (Earlier behavior suppressed on every configured connection by default, which would dial replicas/analytics DBs as a side effect.)
Django Settings
| Setting | Description |
|---|---|
HUSH_DATABASE |
Default database alias |
HUSH_SETTINGS |
Default settings list |
HUSH_STRICT |
Default strict mode |
HUSH_PG_SETTINGS_REGISTRY |
Dict replacing default PG settings |
Running the tests
The project uses uv. Tests require a live PostgreSQL — there is no sqlite fallback.
uv sync # install the dev environment
docker compose up -d # throwaway PostgreSQL on localhost:5432
uv run pytest # run the suite
PG_VERSION selects the PostgreSQL image (default 17); POSTGRES_HOST/PORT/USER/PASSWORD/DB override the connection. Lint and types: uv run ruff check && uv run ruff format --check && uv run mypy.
Requirements
- Python 3.10+
- Django 4.2+
- PostgreSQL 14+ with psycopg2 or psycopg3
License
PostgreSQL License. See LICENSE for details.
Metadata
Release files for django-pgware 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_pgware-1.0.0.tar.gz | 23.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_pgware-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 44.6 kB
Release files / django_pgware-1.0.0.tar.gz
| Download URL | django_pgware-1.0.0.tar.gz |
|---|---|
| Size | 23.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e7aa705861881bf5c7f4a955220051049c86045a56c1c3933f44fc411c447ee6
|
|
BLAKE2b-256 checksum How to use checksums |
afdbd9f6b1e7e3bc07613b019009c2df6d3904e0dbfb7ac73dba4d3f00dc7c6e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 21, 2026.
Transparency logRelease files / django_pgware-1.0.0-py3-none-any.whl
| Download URL | django_pgware-1.0.0-py3-none-any.whl |
|---|---|
| Size | 21.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
658aba06d14e184b2a2e3895b1a1a179bc83cca75207da12ba2c6c2e956443db
|
|
BLAKE2b-256 checksum How to use checksums |
068af474e1b215cfc9c254a3b77377d780082dcbeb9320bd4c98492980c6aee8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 21, 2026.
Transparency log