Skip to main content

Installation & Drivers

DBAnchor is distributed on PyPI and supports Python 3.10, 3.11, 3.12, and 3.13.

You can install the lightweight standalone package or bundle your preferred PostgreSQL driver:

Standard Installation
pip install dbanchor
With psycopg3 or asyncpg Drivers
# For synchronous psycopg3 driver
pip install "dbanchor[psycopg]"

# For asynchronous asyncpg driver
pip install "dbanchor[asyncpg]"

Configuration & Environment

DBAnchor automatically discovers database connection parameters from your system environment or a local .env file in the current working directory.

.env Configuration Example
# Standard PostgreSQL URI
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/my_app_db

# Environment classification: development | staging | production
APP_ENV=development

# Diagnostic probe timeout in seconds (default: 5.0)
DBANCHOR_TIMEOUT=5.0

Running Your First Diagnostic Check

Once configured, run dbx doctor to test all 6 layers of database readiness:

CLI Check
$ dbx doctor
Provider          : Neon Database
Environment       : DEVELOPMENT
Database Engine   : PostgreSQL 17.2
Health Status     : READY

✓ DNS Resolution
✓ TCP Reachability (ep-weather-7281.us-east-2.aws.neon.tech:5432)
✓ SSL Handshake (TLSv1.3 with SNI)
✓ Authentication (user: app_admin)
✓ Schema Permissions (search_path: public)
✓ Migration System (Alembic: 1 pending revision)

Status: READY

Python SDK: Synchronous Engine & Session

The Database class wraps SQLAlchemy engines with built-in connection retry logic, password encoding validation, and credential redaction.

app/main.py
from dbanchor import Database
from sqlalchemy import select
from myapp.models import User

db = Database()

with db.session() as session:
    users = session.scalars(select(User).limit(10)).all()
    for user in users:
        print(user.email)

Async Python & FastAPI Integration

For asynchronous applications using FastAPI, Starlette, or Litestar with asyncpg:

app/api.py
from fastapi import FastAPI
from dbanchor import Database
from sqlalchemy import select
from myapp.models import Item

app = FastAPI()
db = Database()

@app.get("/items")
async def list_items():
    async with db.async_session() as session:
        result = await session.scalars(select(Item))
        return result.all()

Programmatic Health Checking

You can integrate DBAnchor health checks directly into your application's /healthz or readiness probe endpoints:

app/healthz.py
from dbanchor import Database

db = Database()
report = db.check_health()

if not report.is_healthy:
    raise RuntimeError(f"Database not ready: {report.summary}")

Deterministic Error Diagnosis

Translate raw psycopg/asyncpg/SQLAlchemy exceptions into human-readable remedies:

try:
    with db.session() as session:
        session.execute(query)
except Exception as exc:
    diag = db.diagnose(exc)
    print(diag.title)          # e.g., 'Undefined Column'
    print(diag.what_happened)  # e.g., 'Column users.phone does not exist'
    print(diag.remediation)    # e.g., 'Run dbx migrate or dbx schema diff'

Alembic Migration Management

DBAnchor complements Alembic by diagnosing graph divergence, branch collisions, and dry-run execution plans:

# Check migration status
$ dbx migration status

# Plan and inspect upcoming DDL risk
$ dbx migration plan

# Explain multi-head graph divergence
$ dbx migration explain

Schema Drift Detection

Verify whether Python SQLAlchemy models match the live PostgreSQL catalog:

$ dbx schema diff
- Missing Column: users.billing_address (in model, not in DB)
+ Unexpected Column: users.temp_flag (in DB, not in model)
~ Column Type Drift: orders.total (models.Float vs db.NUMERIC(10,2))

Production Safety Rules

When APP_ENV=production, all destructive DDL statements (DROP COLUMN, DROP TABLE, TRUNCATE) are blocked.

To apply an intentional destructive change in production, review the plan with dbx migration plan and pass dbx migrate --force-destructive.

CI/CD Automation: GitHub Actions

Include DBAnchor in pull request checks to prevent broken migrations or schema drift from reaching production:

.github/workflows/db-check.yml
name: Database Health Check
on: [push, pull_request]

jobs:
  db-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      - run: pip install dbanchor psycopg
      - run: dbx doctor --json
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}
          APP_ENV: staging

Process Exit Codes

Exit Code Status Meaning
0 SUCCESS All health checks and migration validations passed.
1 ERROR Diagnostic failure (e.g., unreachable host, auth failure).
2 BLOCKED Destructive DDL blocked by production safety gate.