Metadata-Version: 2.4
Name: pg-deltax
Version: 0.0.2
Summary: Python helpers for the pg_deltax PostgreSQL extension with SQLModel, FastAPI, and Django support.
Project-URL: Homepage, https://github.com/jmitchel3/deltaX-python
Project-URL: Repository, https://github.com/jmitchel3/deltaX-python
Author-email: Justin Mitchel <justin@codingforentrepreneurs.com>
License: MIT
License-File: LICENSE
Keywords: DeltaX,Django,FastAPI,PostgreSQL,SQLModel,pg_deltax,time-series
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: Django
Classifier: Framework :: Django :: 5.2
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: Implementation :: CPython
Requires-Python: >=3.11
Requires-Dist: sqlmodel>=0.0.8
Provides-Extra: dev
Requires-Dist: django>=5.2; extra == 'dev'
Requires-Dist: fastapi>=0.104.0; extra == 'dev'
Requires-Dist: psycopg[binary]>=3.1; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: uvicorn>=0.23.2; extra == 'dev'
Provides-Extra: django
Requires-Dist: django>=5.2; extra == 'django'
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.104.0; extra == 'fastapi'
Requires-Dist: uvicorn>=0.23.2; extra == 'fastapi'
Description-Content-Type: text/markdown

# pg-deltax

`pg-deltax` is a Python companion package for the
[`pg_deltax`](https://github.com/xataio/deltax) PostgreSQL extension. It keeps
the Python layer thin: SQLAlchemy engine/dialect helpers, SQLModel table
shapes, explicit wrappers for the pg_deltax SQL functions, FastAPI session
glue, and a Django app/backend/migration layer.

DeltaX functions are schema-qualified as `deltax.<function>` to match the
extension docs.

## Install

```bash
pip install pg-deltax
pip install "pg-deltax[fastapi]"
pip install "pg-deltax[django]"
```

The database must have `pg_deltax` installed and loadable by PostgreSQL.

The distribution name is `pg-deltax`; the Python import package is `deltax`.

## SQLModel

```python
from sqlmodel import Field
from sqlmodel import Session
from sqlmodel import SQLModel

import deltax


class Metric(deltax.DeltaxModel, table=True):
    sensor_id: int = Field(index=True)
    value: float

    __tablename__ = "metrics"


engine = deltax.create_engine("postgresql+psycopg://user:pass@localhost/db")
SQLModel.metadata.create_all(engine)

with Session(engine) as session:
    deltax.activate_deltax_extension(session)
    deltax.create_deltatable(session, Metric, partition_interval="1 day", premake=3)
    deltax.enable_compression(
        session,
        Metric,
        segment_by=["sensor_id"],
        order_by=["time"],
    )
    deltax.set_compression_policy(session, Metric, "7 days")
    deltax.set_retention(session, Metric, "90 days")
```

`DeltaxModel` uses a composite primary key of `id` and `time`, matching the
partitioning constraints PostgreSQL applies to time-partitioned tables.
DeltaX settings live in explicit `Deltatable` specs or direct function calls,
matching the pg_deltax extension API instead of SQLModel class attributes.
For startup sync, a `Deltatable` spec runs the same pg_deltax setup from an
explicit value:

```python
metric_deltatable = deltax.Deltatable(
    Metric,
    partition_interval="1 day",
    premake=3,
    compression=deltax.CompressionConfig(
        segment_by=["sensor_id"],
        order_by=["time"],
        compress_after="7 days",
    ),
    drop_after="90 days",
)

deltax.create_all(engine, deltatables=[metric_deltatable])
```

Query helpers expose DeltaX analytics functions:

```python
from sqlmodel import Session

with Session(engine) as session:
    rows = deltax.time_bucket_query(
        session,
        Metric,
        interval="1 hour",
        time_field="time",
        metric_field="value",
    )
```

## FastAPI

```python
from fastapi import Depends, FastAPI
from sqlmodel import Session

import deltax

engine = deltax.create_engine("postgresql+psycopg://user:pass@localhost/db")
get_session = deltax.fastapi.create_session_dependency(engine)

app = FastAPI()


@app.on_event("startup")
def startup() -> None:
    deltax.create_all(engine, deltatables=[metric_deltatable])


@app.get("/metrics")
def metrics(session: Session = Depends(get_session)):
    return deltax.time_bucket_query(session, Metric, metric_field="value")
```

## Django

Add the app and use the backend if you want automatic extension creation:

```python
INSTALLED_APPS = [
    "django.contrib.contenttypes",
    "deltax.django",
]

DATABASES = {
    "default": {
        "ENGINE": "deltax.django.db.backends.postgresql",
        "NAME": "app",
        "USER": "postgres",
        "PASSWORD": "postgres",
        "HOST": "localhost",
        "PORT": "5432",
        "OPTIONS": {"deltax_auto_create_extension": True},
    }
}
```

Define models with the Django shims:

```python
from deltax.django.db import models


class Metric(models.DeltaxModel):
    time = models.DeltaxDateTimeField(interval="1 day", primary_key=True)
    sensor_id = models.IntegerField()
    value = models.FloatField()
```

Use migration operations to manage DeltaX:

```python
from django.db import migrations
from deltax.django.db import migrations as deltax_migrations


class Migration(migrations.Migration):
    operations = [
        deltax_migrations.CreateExtension(),
        deltax_migrations.CreateDeltatable("Metric", time_column="time"),
        deltax_migrations.EnableCompression("Metric", segment_by=["sensor_id"]),
        deltax_migrations.SetCompressionPolicy("Metric", compress_after="7 days"),
        deltax_migrations.SetRetention("Metric", drop_after="90 days"),
    ]
```

Querysets can annotate with DeltaX functions:

```python
Metric.objects.time_bucket("1 hour").values("bucket").annotate(avg=models.Avg("value"))
```

## Live pg_deltax check

Use Docker Compose to build a PostgreSQL image with the upstream `pg_deltax`
extension and run the live integration test:

```bash
docker compose up --build --abort-on-container-exit --exit-code-from live-test live-test
```

See [docs/live-pg-deltax.md](docs/live-pg-deltax.md) for details.
