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
- 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}
"""
- 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
DBURLenvironment 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 (ruff, 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 integrationpsycopg3- Use psycopg3 instead of psycopg2
Quick Test Setup
Integration Tests (Requires Database)
-
Start PostgreSQL database:
# Prefer podman if available (for parallel branch testing) # Default PostgreSQL version 15 podman run -d -p 5435:5432 -e POSTGRES_HOST_AUTH_METHOD=trust docker.io/library/postgres:15 # Or with docker: docker run -d -p 5435:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres:15 # Or with docker compose (defaults to PostgreSQL 15): docker compose up -d # Or: docker-compose up -d # Or with docker compose using different version: POSTGRES_VERSION=16 docker compose up -d # Or: POSTGRES_VERSION=16 docker-compose up -d
-
Set database connection:
# Recommended: Use DB_PORT for easy port switching (useful for parallel branches) export DB_PORT=5435 # Or use full connection string: # export DB_URL=postgresql://postgres@localhost:5435/postgres # Or create .env file (copy .env.example and adjust if needed)
-
Run all tests:
uv run pytest
Unit Tests Only (No Database Required)
uv run pytest -m unit
Troubleshooting
- Connection refused: Make sure PostgreSQL is running on port 5435
- Authentication failed: Check
DB_URLformat:postgresql://user@host:port/dbname - Port in use: Change port mapping in
docker-compose.ymlor use different port inDB_URLor setDB_PORT
See TESTING.md for detailed testing guide.
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
ABCtoProtocoltype 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 QuerySetsSamizdatMaterializedQuerySet- Materialized views from QuerySetsSamizdatModel- Unmanaged Django models as viewsSamizdatMaterializedModel- Materialized views from models
- Compat with both
psycopgandpsycopg3 - Opinionated code formatting
- black + isort
- replaced
lambdas
- some simple
pytestfunctions
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:
# Ensure database is ready first (see TESTING.md for setup)
uv run pytest
Note: Always use uv run pytest (not pytest or python -m pytest) to ensure dependencies are available in the virtual environment.
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
Quick Start: See Quick Test Setup above for the fastest way to run tests.
Detailed Setup
Start PostgreSQL database:
Prefer podman if available (useful for parallel branch testing):
# Default PostgreSQL version 15
podman run -d -p 5435:5432 -e POSTGRES_HOST_AUTH_METHOD=trust docker.io/library/postgres:15
# Or use version 16
podman run -d -p 5435:5432 -e POSTGRES_HOST_AUTH_METHOD=trust docker.io/library/postgres:16
Or with Docker:
# Default PostgreSQL version 15
docker run -d -p 5435:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres:15
# Or use version 16
docker run -d -p 5435:5432 -e POSTGRES_HOST_AUTH_METHOD=trust postgres:16
Or with docker compose:
# Default PostgreSQL version 15
docker compose up -d
# Or: docker-compose up -d
# Or use version 16
POSTGRES_VERSION=16 docker compose up -d
# Or: POSTGRES_VERSION=16 docker-compose up -d
Set database connection:
Option 1: Using DB_PORT (Recommended for parallel branches)
export DB_PORT=5435
Option 2: Using full connection string
export DB_URL=postgresql://postgres@localhost:5435/postgres
Option 3: Create .env file
Create a .env file in the project root (copy from .env.example if available):
DB_PORT=5435
POSTGRES_VERSION=15
# Or: DB_URL=postgresql://postgres@localhost:5435/postgres
The test suite will automatically load .env files using python-dotenv.
Note:
- For parallel branch testing, use different ports (e.g., 5435, 5436, 5437) and set
DB_PORTaccordingly. - PostgreSQL version defaults to 15. Set
POSTGRES_VERSIONto use a different version (fordocker composeordocker-compose) or specify the version in the image tag (for podman/docker). - Docker Compose: Use
docker compose(Docker Compose v2, built into Docker) ordocker-compose(standalone). Both work with the samedocker-compose.ymlfile.
Run tests:
# All tests (requires database)
uv run pytest
# Unit tests only (no database required)
uv run pytest -m unit
# Integration tests only (requires database)
uv run pytest -m integration
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 builduv publish- username: token
- token: (get it from pypi)
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 dbsamizdapper-0.1.2.tar.gz.
File metadata
- Download URL: dbsamizdapper-0.1.2.tar.gz
- Upload date:
- Size: 179.3 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
002f0cabc7b8763df45e5016b4df7eed95b650697f00cd8bd6d5d12e55aa3885
|
|
| MD5 |
51fafdb1f2b514107dc649d3618033b8
|
|
| BLAKE2b-256 |
3e2f7a4744ad8354608e7fc11fc077da83cb6eaa878f69f134418ab43fc17c71
|
File details
Details for the file dbsamizdapper-0.1.2-py3-none-any.whl.
File metadata
- Download URL: dbsamizdapper-0.1.2-py3-none-any.whl
- Upload date:
- Size: 63.7 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a1e928168a11fde28ec7cb5586f279fd201e272a80b56abb624455eb51e75f7
|
|
| MD5 |
ebcb8df1487c7d86d4ae6390489e6a19
|
|
| BLAKE2b-256 |
1153e444b82d051bf6e2ce71f19bc92d1d759dcb64917d116a30193935af8afd
|