Skip to main content

Clean up your Django database effortlessly with customizable record removal based on your retention policy

Project description


Django Database Purge

django-db-purge deletes expired database records based on configurable retention policies, run as a scheduled Django management command. It also ships an MCP server so an AI agent can purge records too, safely, behind a preview, token, execute handshake.

Features:

  • Flexible Retention Policy: Define your own retention policy to determine which records should be purged from the database.
  • Efficient Data Management: Easily manage the size of your database by removing outdated or unnecessary records.
  • Customizable: Adapt the command to suit your project's specific requirements and database structure.
  • Safe: Built-in safeguards to prevent accidental data loss, ensuring that only the intended records are purged.
  • Agent-safe MCP tools: Optionally let an AI agent purge records through a preview, token, execute handshake that blocks deletion without a matching prior preview.

Scheduled purging (cron)

How to Use:

  1. Install django-db-purge by running:
pip install django-db-purge
  1. Include 'dbpurge' in your INSTALLED_APPS settings.

  2. Add a DB_PURGE_RETENTION_POLICIES list to your project's settings.py, based on your requirements. Below is a guide on how to set up the retention policies:

    1. app_name

    • Description: Name of the Django app containing the model.
    • Example: my_django_app

    2. model_name

    • Description: Name of the Django model from which records will be deleted.
    • Example: MyModel

    3. time_based_column_name

    • Description: Name of the column in the model that contains the timestamp or datetime field used for determining the age of records.
    • Example: created_at

    4. data_retention_num_seconds

    • Description: Time duration in seconds for which records will be retained before deletion.
    • Example: 2592000 (for 30 days)

    Example:

    # settings.py
    DB_PURGE_RETENTION_POLICIES = [
        {
            'app_name': 'my_django_app',
            'model_name': 'MyModel',
            'time_based_column_name': 'created_at',
            'data_retention_num_seconds': 2592000,  # 30 days in seconds
        },
        # Add more retention policies as needed
    ]
    

    If DB_PURGE_RETENTION_POLICIES is not set, the command falls back to a placeholder policy that will fail validation until you configure it, so there's no risk of silently deleting the wrong table.

  3. Then, either periodically call the db_purge management command (e.g., via a system cronjob), or install and configure django-cron.


MCP server

django-db-purge also ships an MCP server that exposes the same purge logic to an AI agent, with guardrails so an agent can never delete rows without a human-verifiable preview step. It runs inside Django as a management command and speaks the MCP protocol over stdio, so it works with Claude Desktop, the MCP Inspector, or any other MCP-capable host. The server makes no LLM API calls of its own: the host runs the model, and this process only exposes deterministic, schema-validated tools.

Installation

The MCP server needs fastmcp, which is an optional extra, not part of the base install:

pip install "django-db-purge[mcp]"

If fastmcp is not installed, running purge_mcp_server fails immediately with a CommandError pointing back at this install command, rather than a raw import traceback.

Tools

  • list_purge_candidates() Read-only. Introspects installed models and returns every app, model, and DateField/DateTimeField column, so an agent can discover valid inputs for the other two tools.

  • preview_purge(app_name, model_name, time_column, retention_seconds) Read-only. Validates the policy against live schema, counts matching rows, and returns up to 5 sample rows (primary key and the time column only, never the full row), a confirmation_token, and token_expires_at. Performs no deletion.

  • execute_purge(app_name, model_name, time_column, retention_seconds, confirmation_token) Deletes the matching rows, but only with a confirmation_token from a matching preview_purge call. Any unknown token, expired token, or parameter mismatch fails with the same "invalid or expired confirmation token" error, so a caller can't distinguish which of those it was.

Safety handshake

There is no path to deletion without a prior, matching preview:

  1. Call preview_purge to see what would be deleted and get back a confirmation_token.
  2. Call execute_purge with that token and the identical parameters, before it expires (5 minutes).

Tokens are single-use: a successful execute_purge consumes the token, so it cannot be replayed. Tokens are also bound to the exact parameter tuple that produced them, so changing any argument invalidates the token even if it hasn't expired. If execute_purge fails for a reason that isn't the caller's fault, such as a row-cap breach below, the token is reinstated so a retry with the same token can still succeed.

Settings

  • DB_PURGE_MCP_ALLOWED_MODELS List of models that may be purged via MCP, in "app_label.ModelName" format (e.g. ["tests.SampleRecord"]). Matched case-insensitively, so "tests.samplerecord" also works. Defaults to an empty list, meaning nothing is purgeable until you configure it. Enforced on both preview_purge and execute_purge.

  • DB_PURGE_MCP_MAX_ROWS Maximum number of matching rows an execute_purge call may delete, re-checked at execute time even if the preview was under the cap. Defaults to 10000. This bounds the rows matched by time_column, not cascade fan-out: ON DELETE CASCADE relations can remove additional related rows beyond this cap.

Running the server

Inside your project's virtualenv, with dbpurge in INSTALLED_APPS:

python manage.py purge_mcp_server

This boots Django (settings, ORM, app registry) and then serves the three tools above over stdio.

Claude Desktop configuration

Add an entry to Claude Desktop's claude_desktop_config.json, pointing at your project's virtualenv Python and manage.py:

{
  "mcpServers": {
    "django-db-purge": {
      "command": "/path/to/your/project/.venv/bin/python",
      "args": ["/path/to/your/project/manage.py", "purge_mcp_server"],
      "cwd": "/path/to/your/project"
    }
  }
}

Use the venv's Python directly (not a bare python), since fastmcp and your project's dependencies need to be importable.

Inspecting the server

To poke at the tools interactively, run the server through the MCP Inspector:

npx @modelcontextprotocol/inspector python manage.py purge_mcp_server

Run this from inside your project's virtualenv (activated, or with that venv's python on PATH), so the python the Inspector spawns is the one with Django and fastmcp installed.

A healthy tools/list response shows all three tools: list_purge_candidates, preview_purge, and execute_purge, each with a JSON schema derived from its type hints.

Running the tests

From a bare checkout, with this package installed with the mcp extra (pip install -e ".[mcp]"), no separate install step for Django or fastmcp is required:

python runtests.py

This runs the full Django test suite, including token lifecycle, allowlist, and row-cap coverage, against an in-memory sqlite database.

To exercise the server the way a real MCP client would, over an actual stdio subprocess:

python tests/e2e_stdio.py

This seeds a temporary sqlite database, spawns python -m django purge_mcp_server, and drives a full preview, execute, and reuse-rejected round trip over JSON-RPC.

Contributions:

Contributions are welcome! If you encounter any issues or have suggestions for improvements, please submit an issue or pull request on GitHub.

License:

This project is licensed under the MIT License.


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_db_purge-1.2.0.tar.gz (20.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_db_purge-1.2.0-py3-none-any.whl (13.2 kB view details)

Uploaded Python 3

File details

Details for the file django_db_purge-1.2.0.tar.gz.

File metadata

  • Download URL: django_db_purge-1.2.0.tar.gz
  • Upload date:
  • Size: 20.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for django_db_purge-1.2.0.tar.gz
Algorithm Hash digest
SHA256 302c68882e389d846115aaa338121bb9a312300f0b81e343c8821730e1a13fc6
MD5 0fe3a17273c56d6e13b0b6cad4a05467
BLAKE2b-256 ceefc952f51b027f3b71e2b9395548877436e2d3835c8036b5a800dca2ba07b0

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_db_purge-1.2.0.tar.gz:

Publisher: publish.yml on topunix/django-db-purge

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_db_purge-1.2.0-py3-none-any.whl.

File metadata

  • Download URL: django_db_purge-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 13.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for django_db_purge-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6ed77808f649c051fb0016082fc888cd8f5a8ab519b15548d423ad94f3d7955b
MD5 2c2fcfcf79ac6cba19b70dc03490914f
BLAKE2b-256 9a4862d4aea9d89f3bd9bcc39a6bc0d8ea75f40122f39d41953bdeedee8244c9

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_db_purge-1.2.0-py3-none-any.whl:

Publisher: publish.yml on topunix/django-db-purge

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