Metadata-Version: 2.3
Name: pgcraft
Version: 0.12.0
Summary: Configuration-driven PostgreSQL framework
Keywords: postgresql,sqlalchemy,alembic,postgrest,migrations
Author: Rodda John
Author-email: Rodda John <roddarjohn@protonmail.com>
License: MIT License
         
         Copyright (c) 2026 Rodda John
         
         Permission is hereby granted, free of charge, to any person obtaining a copy
         of this software and associated documentation files (the "Software"), to deal
         in the Software without restriction, including without limitation the rights
         to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         copies of the Software, and to permit persons to whom the Software is
         furnished to do so, subject to the following conditions:
         
         The above copyright notice and this permission notice shall be included in all
         copies or substantial portions of the Software.
         
         THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
         SOFTWARE.
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Database
Classifier: Typing :: Typed
Requires-Dist: alembic>=1.18.4
Requires-Dist: mako>=1.3.10
Requires-Dist: pglast>=7.11
Requires-Dist: sqlalchemy>=2.0.48
Requires-Dist: sqlalchemy-declarative-extensions>=0.16.8
Requires-Dist: sqlfluff>=3.3
Requires-Dist: typer>=0.24.1
Requires-Python: >=3.12
Project-URL: Homepage, https://github.com/roddarjohn/pgcraft
Project-URL: Documentation, https://roddarjohn.github.io/pgcraft/
Project-URL: Repository, https://github.com/roddarjohn/pgcraft
Project-URL: Changelog, https://github.com/roddarjohn/pgcraft/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/roddarjohn/pgcraft/issues
Description-Content-Type: text/markdown

# pgcraft

[![PyPI](https://img.shields.io/pypi/v/pgcraft)](https://pypi.org/project/pgcraft/)
[![Documentation](https://img.shields.io/badge/docs-GitHub%20Pages-blue)](https://roddarjohn.github.io/pgcraft/)

> **Pre-alpha** — pgcraft is under active development. APIs may change
> between releases. Feedback and contributions are welcome.

**Configuration-driven PostgreSQL data schemas, migrations, and APIs.**

pgcraft generates SQLAlchemy models and Alembic migrations from
declarative dimension configurations. Define your schema once;
pgcraft handles the rest. An optional
[PostgREST](https://postgrest.org) extension adds API views,
roles, and grants.

---

## Features

- **Dimension types** — Simple, Append-Only (SCD Type 2), and
  Entity-Attribute-Value, each with generated backing tables, views, and
  triggers.
- **Plugin architecture** — Composable plugins with `@requires` / `@produces`
  decorators, executed in topological order.
- **Automatic migrations** — Alembic integration with SQL-formatted migration
  scripts via sqlglot.
- **Extension system** — Opt-in extensions for PostgREST API views,
  roles, and grants. Third-party extensions via entry points.
- **Postgres is king** — Logic lives in the database (views, triggers, check
  constraints). Python orchestrates; Postgres enforces.

## Quick start

### Install

```bash
pip install pgcraft            # or: uv add pgcraft
```

### Define a dimension

```python
from sqlalchemy import Column, MetaData, String
from pgcraft import PGCraftBase, pgcraft_build_naming_conventions

metadata = MetaData(naming_convention=pgcraft_build_naming_conventions())


class Base(PGCraftBase):
    metadata = metadata


class Users(Base):
    __tablename__ = "users"
    __table_args__ = {"schema": "public"}

    name = Column(String, nullable=False)
    email = Column(String)
```

This creates a `public.users` table with `id`, `name`, and `email`
columns, with Alembic migration support out of the box.

### Generate migrations

```bash
pgcraft migrate revision --autogenerate -m "add users"
pgcraft migrate upgrade head
```

## Dimension types

pgcraft ships with three built-in dimension types:

| Type | Use case | History? |
|------|----------|----------|
| **Simple** | Static reference data | No |
| **Append-Only** (SCD Type 2) | Track changes over time | Yes |
| **EAV** | Flexible / sparse attributes with full audit trail | Yes |

See the [dimensions documentation](https://roddarjohn.github.io/pgcraft/dimensions.html) for ERD diagrams, schema details, and worked examples.

## Documentation

Full documentation is available at
[roddarjohn.github.io/pgcraft](https://roddarjohn.github.io/pgcraft/).

- [Setup & installation](https://roddarjohn.github.io/pgcraft/setup.html)
- [Built-in dimensions](https://roddarjohn.github.io/pgcraft/dimensions.html)
- [Plugin system](https://roddarjohn.github.io/pgcraft/plugins.html)
- [Extensions](https://roddarjohn.github.io/pgcraft/extensions.html)
- [API reference](https://roddarjohn.github.io/pgcraft/api.html)
- [Development guide](https://roddarjohn.github.io/pgcraft/development.html)
- [Playground](https://roddarjohn.github.io/pgcraft/playground.html)

## Development

```bash
# Clone and install
git clone https://github.com/<username>/pgcraft.git
cd pgcraft
uv sync --all-groups

# Run checks
just lint          # ruff check + format
just type-check    # zuban check src/
just dev-test      # pytest (fast, needs DATABASE_URL)
just test          # tox (full isolation)
just docs          # build Sphinx HTML docs
```

Tests require a running PostgreSQL instance:

```bash
DATABASE_URL=postgresql+psycopg:///pgcraft just dev-test
```

## Design philosophy

See [PLAN.md](PLAN.md) for the full design philosophy. The short version:

- **Explicit over implicit.** No magic — if behavior is not obvious from
  reading the code, it needs a docstring explaining *why*.
- **Simple over clever.** Three similar lines are better than a premature
  abstraction.

## License

See [LICENSE](LICENSE) for details.
