Reusable Django management command for PostgreSQL lifecycle, backup, and restore tasks.
Project description
django-postgres-man-db
man_db is a small, reusable Django app that provides management commands to manage PostgreSQL databases and backups. It is intended to be dropped into Django projects that use Postgres.
Features
- Management commands (two entry points:
man_dbandmandb) to perform common Postgres lifecycle tasks:create— create the configured PostgreSQL databasedrop— terminate connections and drop the database (destructive)reset— delete local app migration files and drop the database (destructive)ping— check that PostgreSQL is reachablebackup— create apg_dumpcustom-format archiverestore— restore apg_restorearchive (destructive)
Requirements
- Python >= 3.11
- Django >= 5.2
psycopg[binary]andstructlog(declared inpyproject.toml)pg_dumpandpg_restorebinaries available onPATH(or provided via env vars)
See pyproject.toml for package metadata and declared dependencies.
Installation
For Django projects that consume a published release, install from PyPI:
uv add django-postgres-man-db
# or
pip install django-postgres-man-db
For local development from this repository, use an editable install:
python -m venv .venv
source .venv/bin/activate
pip install -e .
Then add man_db to your Django INSTALLED_APPS.
# settings.py
INSTALLED_APPS = [
# ...
"man_db",
]
Ensure the DATABASES[...] entry you intend to manage uses the Postgres backend (django.db.backends.postgresql). The management commands read connection details from settings.DATABASES.
Environment variables
PG_DUMP_PATH— optional absolute path to thepg_dumpexecutable. If unset, the command will look forpg_dumponPATH, but only from trusted executable directories.PG_RESTORE_PATH— optional absolute path to thepg_restoreexecutable. If unset, the command will look forpg_restoreonPATH, but only from trusted executable directories.PGPASSWORD— if your DB password is set inDATABASES[...], the package will setPGPASSWORDin the subprocess environment forpg_dump/pg_restore.SERVICE_NAME/ENVIRONMENT— optional values used to bind contextvars forstructlog(defaults:man_db/local).
Optional Django settings
MAN_DB_TRUSTED_EXECUTABLE_DIRS— iterable of trusted directories forpg_dumpandpg_restorePATH fallback. Defaults to common system binary locations such as/usr/bin,/usr/local/bin, and/usr/lib/postgresql.MAN_DB_RESET_APP_ALLOWLIST— iterable of app labels allowed forresetmigration deletion when--appsis not passed.
Usage
The package exposes two management command names that are equivalent:
python manage.py man_db <action> [options]
python manage.py mandb <action> [options]
Common examples:
# create the database
python manage.py man_db create
Specifying the database name
The management commands read database connection information from your Django project's settings.DATABASES. The important field for create, backup, and restore actions is the NAME value under the selected database alias.
Example settings.py (using environment variables is recommended for secrets):
import os
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": os.environ.get("DB_NAME", "my_database_name"),
"USER": os.environ.get("DB_USER", "app_user"),
"PASSWORD": os.environ.get("DB_PASSWORD", "secret"),
"HOST": os.environ.get("DB_HOST", "db.example"),
"PORT": int(os.environ.get("DB_PORT", 5432)),
},
"analytics": {
"ENGINE": "django.db.backends.postgresql",
"NAME": "analytics_db",
"USER": "analytics_user",
"PASSWORD": "secret",
"HOST": "db.example",
"PORT": 5432,
},
}
How the commands select the database:
- Use the
--databaseoption to select a Django database alias (default:default). The command reads theNAMEfrom that alias. - Example:
python manage.py man_db create --database analyticswill attempt to create the database named byDATABASES["analytics"]["NAME"].
Important notes:
- The
createaction requires a non-emptyNAME. IfDATABASES[alias]["NAME"]is empty, the command raises aCommandErrorand refuses to proceed. - For
restore, you may use--create-dbto tellpg_restoreto create the database from the archive; when--create-dbis used the command allows an emptyNAMEbecause the archive can provide the database name. - Keep credentials out of source by using
os.environ.get(...)or a secrets manager in yoursettings.py.
More examples:
# check connectivity for a named DB alias
python manage.py man_db ping --database reporting
# create a backup (output dir, optional prefix)
python manage.py man_db backup --output-dir ./backups --prefix nightly
# restore from backup (destructive)
python manage.py man_db restore --backup ./backups/app_20260516_20260516_010203.dump --i-understand
# reset scoped app migrations and drop DB (destructive, must pass --yes)
python manage.py man_db reset --yes --apps my_app another_app
Important flags
--yes— required to confirm destructive actions (drop,reset).--apps— app labels whose migrations may be deleted duringreset.--database— Django database alias (default:default).--output-dir— directory to write backups to (default:<BASE_DIR>/backups).--prefix— optional filename prefix for backups (must be a single filename component).--compression— compression level forpg_dumpcustom format (0–9; default: 6).--include-owner— include original object owners and privileges in dumps/restores.--backup— path to the.dumparchive to restore.--create-db— when restoring, create the DB from the archive (-Ctopg_restore).--jobs— number of parallel jobs forpg_restore(default: 2, maximum: local CPU count).--i-understand— required to acknowledge destructive restore operations.
Behavior notes
- Backup files are created with a timestamped filename. The implementation ensures generated backup paths cannot escape the requested
--output-dir. - Backup and restore executable paths must be absolute executable files when provided through
PG_DUMP_PATHorPG_RESTORE_PATH. - PATH fallback for
pg_dumpandpg_restoreis restricted to trusted executable directories. - Restore is destructive by default; the command refuses to run unless
--i-understandis provided. restorevalidates--jobsand rejects values outside1..os.cpu_count().resetdeletes migration files only for explicitly scoped app labels from--appsorMAN_DB_RESET_APP_ALLOWLIST, and then drops the configured database.
Logging & events
Logging is implemented with structlog. Events are emitted with a log_name (Application, System, Audit) and an event_code (see src/man_db/event_codes.py). The package binds SERVICE_NAME and ENVIRONMENT context variables if present.
If you want to see or persist these structured logs, configure structlog/the stdlib logger in your project as you would normally.
Running tests
The repository includes unit tests that use Django's test framework. To run tests locally:
python -m pip install -e .
python -m pytest -q
Tests rely on DJANGO_SETTINGS_MODULE being set to tests.settings, which the test modules set by default.
Development and contributing
- Fork and open a PR with a clear description of the change.
- Keep changes focused and include tests for new behavior.
- Run the test suite before submitting:
python -m pytest.
License
This project is licensed under the MIT License (see pyproject.toml).
Author
Letlaka
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_postgres_man_db-0.1.1.tar.gz.
File metadata
- Download URL: django_postgres_man_db-0.1.1.tar.gz
- Upload date:
- Size: 15.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cd2e95f34a4f48c798c59497b91d6e942389f7b349a9ee8b90e8076f7d0e8daf
|
|
| MD5 |
7614ab2bce45d130b48fe99a0033ef16
|
|
| BLAKE2b-256 |
dca875e91b026591501250fdae2ba13c5351c68b8766d95185ffbe3606eebd53
|
Provenance
The following attestation bundles were made for django_postgres_man_db-0.1.1.tar.gz:
Publisher:
publish.yml on Letlaka/man_db
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_postgres_man_db-0.1.1.tar.gz -
Subject digest:
cd2e95f34a4f48c798c59497b91d6e942389f7b349a9ee8b90e8076f7d0e8daf - Sigstore transparency entry: 1698239595
- Sigstore integration time:
-
Permalink:
Letlaka/man_db@c80ad132e8e861c516d2515218f0c95062ac6797 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/Letlaka
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c80ad132e8e861c516d2515218f0c95062ac6797 -
Trigger Event:
push
-
Statement type:
File details
Details for the file django_postgres_man_db-0.1.1-py3-none-any.whl.
File metadata
- Download URL: django_postgres_man_db-0.1.1-py3-none-any.whl
- Upload date:
- Size: 16.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a0e4eb19428bf1fb3711882d327533c092d98c41de8de683adcf389199e145c3
|
|
| MD5 |
5f09c471ed464499348c92ec1269e404
|
|
| BLAKE2b-256 |
32e71fde0578bb2016f5e8c9eb096afcc0b218f31a7d5d6030504911638c480a
|
Provenance
The following attestation bundles were made for django_postgres_man_db-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on Letlaka/man_db
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_postgres_man_db-0.1.1-py3-none-any.whl -
Subject digest:
a0e4eb19428bf1fb3711882d327533c092d98c41de8de683adcf389199e145c3 - Sigstore transparency entry: 1698239711
- Sigstore integration time:
-
Permalink:
Letlaka/man_db@c80ad132e8e861c516d2515218f0c95062ac6797 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/Letlaka
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c80ad132e8e861c516d2515218f0c95062ac6797 -
Trigger Event:
push
-
Statement type: