Skip to main content

Blissfully naive PostgreSQL database object manager for views, materialized views, functions, and triggers

Project description

Dbsamizdapper

The "blissfully naive PostgreSQL database object manager" This is based on the original dbsamizdat code from https://git.sr.ht/~nullenenenen/DBSamizdat/ a version of which was previously hosted at https://github.com/catalpainternational/dbsamizdat

Full disclosure: That one (https://git.sr.ht/~nullenenenen/DBSamizdat/ which is also on pypi) is definitely less likely to have bugs, it was written by a better coder than I am, the original author is "nullenenenen nullenenenen@gavagai.eu"

Quick Start

For detailed usage examples, see USAGE.md

Basic Example

  1. Create a module with your database views:
# myapp/views.py
from dbsamizdat import SamizdatView

class UserStats(SamizdatView):
    sql_template = """
        ${preamble}
        SELECT COUNT(*) as total_users FROM users
        ${postamble}
    """
  1. Sync to your database:
# Using CLI (modules are automatically imported)
python -m dbsamizdat.runner sync postgresql:///mydb myapp.views

# Or using library API
python -c "from dbsamizdat import sync; sync('postgresql:///mydb', samizdatmodules=['myapp.views'])"

Key Points

  • Module Import: The CLI automatically imports modules you specify - no need to manually import them first
  • Database Connection: Use DBURL environment variable or pass connection string directly
  • Python 3.12+: Requires Python 3.12 or later
  • PostgreSQL Only: Works exclusively with PostgreSQL databases
  • Dollar-Quoting: $$ does not work in SQL functions - use tags like $BODY$ instead (see USAGE.md)

Installation

For Users

pip install dbsamizdapper

For Development

This project uses UV for fast dependency management.

Install UV:

curl -LsSf https://astral.sh/uv/install.sh | sh
# or
pip install uv

Setup development environment:

# Clone the repository
git clone <repo-url>
cd dbsamizdapper

# Install dependencies (includes dev tools)
uv sync --group dev --group testing

# Optional: Install Django type stubs for Django integration development
uv sync --group dev --group testing --extra django

Available dependency groups (development):

  • dev - Development tools (black, isort, flake8, mypy, etc.)
  • testing - Test framework and PostgreSQL testing with psycopg2-binary

Available extras (optional runtime features):

  • django - Django 4.2 and type stubs for Django integration
  • psycopg3 - Use psycopg3 instead of psycopg2

New features

This fork is based on a rewrite which I did to better understand the internals of dbsamizdat as we use it in a few different projects. The changes include:

  • Python 3.12+
  • Type hints throughout the codebase
  • Changed from ABC to Protocol type for inheritance
  • UV for fast dependency management
  • Table Management (new in 0.0.6)
    • SamizdatTable - Manage database tables as Samizdat objects
    • UNLOGGED table support for performance-critical use cases
  • Django QuerySet integration (0.0.5)
    • SamizdatQuerySet - Create views from Django QuerySets
    • SamizdatMaterializedQuerySet - Materialized views from QuerySets
    • SamizdatModel - Unmanaged Django models as views
    • SamizdatMaterializedModel - Materialized views from models
  • Compat with both psycopg and psycopg3
  • Opinionated code formatting
    • black + isort
    • replaced lambdas
  • some simple pytest functions

and probably many more undocumented changes

Table Management Example

from dbsamizdat import SamizdatTable

class MyTable(SamizdatTable):
    """Manage a table as a Samizdat object"""
    sql_template = """
    CREATE TABLE ${samizdatname} (
        id SERIAL PRIMARY KEY,
        name TEXT NOT NULL,
        created_at TIMESTAMP DEFAULT NOW()
    )
    """

class MyCacheTable(SamizdatTable):
    """UNLOGGED table for better performance"""
    unlogged = True
    sql_template = """
    CREATE TABLE ${samizdatname} (
        key TEXT PRIMARY KEY,
        value JSONB,
        expires_at TIMESTAMP
    )
    """

Django QuerySet Example

from dbsamizdat import SamizdatMaterializedQuerySet
from myapp.models import MyModel

class MyComplexView(SamizdatMaterializedQuerySet):
    """Create a materialized view from a complex QuerySet"""
    queryset = MyModel.objects.select_related('related').filter(
        active=True
    ).annotate(
        custom_field=F('field1') + F('field2')
    )

    # Optionally specify tables that trigger refresh
    refresh_triggers = [("myapp", "mymodel")]

Development Commands

Run tests:

uv run pytest

Linting and formatting:

uv run ruff check .
uv run ruff format .
uv run mypy dbsamizdat

Pre-commit hooks: This project uses pre-commit for automated code quality checks. Install it using uv:

# Install pre-commit with uv (recommended method)
uv tool install pre-commit --with pre-commit-uv

# Install Git hooks (runs automatically on commit)
pre-commit install

# Run on all files manually
pre-commit run --all-files

# Run on staged files only
pre-commit run

# Run a specific hook
pre-commit run ruff --all-files

# Update pre-commit hooks to latest versions
pre-commit autoupdate

# Upgrade pre-commit itself
uv tool upgrade pre-commit

Note: Pre-commit hooks will automatically run when you commit. To skip hooks (not recommended), use git commit --no-verify.

Build package:

uv build

Running Tests

Spin up a podman or docker container

podman run -p 5435:5432 -e POSTGRES_HOST_AUTH_METHOD=trust docker.io/library/postgres docker run -p 5435:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres:latest

The db url for this container would be:

"postgresql:///postgres@localhost:5435/postgres"

Make this the environment variable DB_URL, or add it to the .env file

Documentation

  • USAGE.md - Comprehensive usage guide with examples for:
    • Non-Django projects
    • Django integration
    • Library API usage
    • Common patterns and troubleshooting

Original README

Check out README.original.md for the original rationale and advanced features

Publishing

  • bump the version number in pyproject.toml
  • tag a release on github
  • uv build
  • uv publish
    • username: token
    • token: (get it from pypi)

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

dbsamizdapper-0.1.1.tar.gz (146.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dbsamizdapper-0.1.1-py3-none-any.whl (58.3 kB view details)

Uploaded Python 3

File details

Details for the file dbsamizdapper-0.1.1.tar.gz.

File metadata

  • Download URL: dbsamizdapper-0.1.1.tar.gz
  • Upload date:
  • Size: 146.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.9 {"installer":{"name":"uv","version":"0.9.9"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for dbsamizdapper-0.1.1.tar.gz
Algorithm Hash digest
SHA256 bbe948a748ce1d3bfa51630d20df6431b4ec03e042eeb84d74c4bafe83505602
MD5 248624af7ac525441321a727def06be2
BLAKE2b-256 9096a98bd95eced46a64e67ed8d52dde072737b163284ef22ca1b752f3c3b810

See more details on using hashes here.

File details

Details for the file dbsamizdapper-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: dbsamizdapper-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 58.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.9 {"installer":{"name":"uv","version":"0.9.9"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for dbsamizdapper-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c601bdc8631ff9659997192f1f6e54f96030e321a5a7f3736b22df7026f0c1b0
MD5 9c880d42f1a05b80d4db06b2d700a2bf
BLAKE2b-256 3537006f3d3bc1e43d3575a1178d5bde6fe2d6cd64db921600b627e2337c3fbc

See more details on using hashes here.

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