Skip to main content

Caspian DB

Native Python tooling for Caspian's Prisma schema, generated client, reviewed SQL migrations, and app-owned Python seed. Distribution: caspian-db; import: caspian_db; command: caspian-db. Python 3.14 or newer. No Node/npm subprocess.

Install

From PyPI, with the driver extra for your provider (postgresql, mysql, or sqlite):

uv add "caspian-db[postgresql]"
# or: pip install "caspian-db[postgresql]"

Then, from your Caspian application:

uv run caspian-db validate
uv run caspian-db generate
uv run caspian-db generate --check

By default the schema is read from prisma/ and the client is generated into src/lib/prisma. Use --schema and --output to choose other locations:

uv run caspian-db generate --schema path/to/schema.prisma --output path/to/client

uv run python -m caspian_db provides the same interface. Commands use the current project directory; pass explicit paths when running elsewhere. uv build produces an installable wheel and source distribution.

Schema and client

--schema accepts a .prisma file or a directory containing multiple .prisma files. Default: prisma. Generation reads source directly; no generated metadata manifest is needed. --metadata remains an explicit legacy compatibility input.

Supported client providers: PostgreSQL, MySQL, and SQLite. The strict schema reader supports models/enums, mappings, optional/list fields, defaults, updatedAt, named relations and inverse relations, compound primary/unique keys, and native-type annotations. It rejects unsupported declarations and attributes instead of silently dropping models. Supported scalar types: String, Int, Boolean, DateTime, Float, BigInt, Decimal, Json. Multi-schema, views, composite types, ignore/fulltext, expression/sorted compound keys, and Bytes/Unsupported types are not implemented. Mapped names currently accept letters/digits/underscores/spaces/periods/hyphens. This is a Caspian schema reader, not the complete Prisma language validator.

The schema holds models, enums, and a datasource provider. Prisma (TypeScript) configuration that the Python client does not read still parses, so a copied schema loads, but validate and generate print a warning naming file:line and the fix for each occurrence: a datasource url, directUrl, or shadowDatabaseUrl (the connection comes from DATABASE_URL in .env) and any generator block (the client comes from caspian-db generate). Remove what a warning names; warnings do not change the exit status.

Generated files remain models.py, db.py, and __init__.py. App imports such as from src.lib.prisma import prisma and existing delegate/query APIs are preserved. validate checks schema and generated syntax; generate --check checks the client against source. Neither compares a live database's structure to the schema. Native type, index, and foreign-key action annotations describe database structure; the client generator does not apply them. Express those changes in migration SQL.

upsert keeps Prisma's meaning: create applies to a new row and update to an existing one. On the native ON CONFLICT / ON DUPLICATE KEY path, a column whose update value is exactly its create value (same type and value) is set from the proposed row (EXCLUDED.col, excluded.col, VALUES(col)) instead of binding the same parameter twice, so a large value is sent once. The stored row is the same; a BEFORE INSERT trigger that rewrites such a column would be visible through it.

All outputs compile before publication. A process lock serializes writers; staged per-file replacements roll back on write errors. Authored files and file symlinks are refused. Unchanged output keeps timestamps. Publication is not a crash-atomic directory swap: stop Python before generation and regenerate after an interrupted publication. No watchers, automatic reloads, seeds, or migrations run implicitly.

Reviewed SQL migrations

uv run caspian-db migrate diff                      # print the SQL for schema changes; writes nothing
uv run caspian-db migrate create --name add_profile # write it as a migration
uv run caspian-db migrate status                    # pending migrations, unmigrated schema changes
uv run caspian-db migrate deploy

Every migration folder keeps schema.json, the structure the schema described when the migration was created. create diffs the current schema against the latest snapshot and writes migration.sql with Prisma's SQL conventions (T_pkey, T_col_key, T_col_idx, T_col_fkey, RESTRICT/SET NULL + CASCADE), plus the new snapshot. It reads no database. Review the SQL before deploying:

  • Steps that lose data or can fail on existing rows (dropped tables and columns, a required column without a default, a type change, a column becoming required) are preceded by -- WARNING: lines and printed by the command.
  • PostgreSQL alters columns, keys, indexes, and enum values in place. Removing an enum value is a -- TODO: block.
  • SQLite adds tables, columns (including a new optional foreign key), and indexes in place. A change SQLite cannot make with ALTER TABLE (a column's type, nullability, or default, a primary key, a foreign key on an existing column) is a -- TODO: block with the new table definition to rebuild by hand.

A history created before snapshots existed has none; create then stops. When the schema matches the deployed database, uv run caspian-db migrate snapshot records it beside the latest migration, and later create runs diff from there. create --empty writes a migration to fill in by hand (with its snapshot).

status uses a read-only transaction, reports pending SQL, and says whether the schema has changes no migration captures yet. deploy is an explicit database write operation. Review its target and SQL first. Commands accept --schema and --migrations. DATABASE_URL loads from the current project's .env unless already set in the environment; credentials are not printed.

Deployment supports PostgreSQL and SQLite. Provider mismatch, changed/missing applied migrations, non-prefix history, and unresolved failures stop deployment. Existing _prisma_migrations records and original SQL file checksums are reused; there is no automatic baseline or replay. Local migration_lock.toml is preserved. PostgreSQL uses a transaction advisory lock; SQLite uses BEGIN IMMEDIATE. Pending SQL and ledger entries commit together as one batch; a failure rolls back the batch. Transaction controls and nontransactional operations such as CONCURRENTLY are refused. SQL is trusted, reviewed project source, not uploaded/untrusted input.

Failed existing Prisma migrations need deliberate recovery; this package does not provide an automatic resolve/reset command. Recovery uses a reviewed follow-up migration or explicit DBA intervention. It does not generate down migrations, perform schema drift detection, db push/introspection, or provide Prisma Studio. MySQL client generation remains supported; MySQL migration deployment is not implemented because its DDL transaction semantics need a separate runner.

Python seed

uv run caspian-db seed
uv run caspian-db seed --demo-user

seed loads prisma/seed.py (override with --file) and awaits its run(demo_user=...) function. The consuming app owns the seed policy. Never execute seeds implicitly. The migrated Caspian app seed creates missing Admin/User roles in a transaction, keeps existing records unchanged, and never deletes users or resets counters. The optional demo user requires CASPIAN_SEED_DEMO_PASSWORD, hashes it, and does not replace an existing user's credentials. No built-in destructive reset is supplied.

Dependencies and verification

Generation/schema reading uses the standard library. Migration SQL classification uses sqlparse; environment loading uses python-dotenv. Generated clients need the provider driver; extras: caspian-db[postgresql], [mysql], [sqlite]. The app already installs its drivers. For exact ID default formats, install cuid2, nanoid, or python-ulid; the preserved client otherwise falls back to UUID.

uv sync --group dev
uv run python -m pytest tests -q
uv run ruff check src tests
uv build

Tests include independent legacy-output AST parity for three client providers, native multi-file parsing, no-Node execution, preservation on failure, concurrency, and SQLite migration history/rollback plus generated-client CRUD. The consuming app has an opt-in PostgreSQL test using only session-local temporary tables to verify deployment, history, rollback, additive seeding, and client operations. MySQL execution is still unverified. Read PORTING.md and AGENTS.md before edits.

Metadata

Release files for caspian-db 0.0.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for caspian-db 0.0.5
File Size Uploaded Provenance Actions
caspian_db-0.0.5.tar.gz 106.6 kB Without provenance Details for caspian_db-0.0.5.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for caspian-db 0.0.5
File Interpreter ABI Platform Actions
caspian_db-0.0.5-py3-none-any.whl Python 3 none any Details for caspian_db-0.0.5-py3-none-any.whl

Total release size: 200.9 kB

Release files / caspian_db-0.0.5.tar.gz

Download URL caspian_db-0.0.5.tar.gz
Size 106.6 kB
Tags Source
SHA-256 checksum
How to use checksums
94a01f735a8bc5ddba15a947026b63267538ff3ca052c6f657658953b57641c8
BLAKE2b-256 checksum
How to use checksums
3030b2d79e348b50650e17de20fbc5f9fec6f33c62e355deb29e5ad7acdfb34c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / caspian_db-0.0.5-py3-none-any.whl

Download URL caspian_db-0.0.5-py3-none-any.whl
Size 94.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1e4a17038ea7d5abdb12e14ad79f8714ffcb44924d4e00d411d795d487de1104
BLAKE2b-256 checksum
How to use checksums
fc7c088e79ae598a9ccc8fd04c1e5202ab8cb3558f536c6caee888b82ae6518d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for caspian-db 0.0.5

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page