A helper for developing with Postgres
Project description
pgdevkit
A helper for developing with Postgres.
pgdb compare
Compare a directory of SQL scripts (see the database-in-source layout
convention) against a live database and report differences:
pgdb compare --url postgresql://user:pass@host:port/db path/to/database/
Entra ID auth (Azure Postgres / Databricks Lakebase)
Pass --entra-user <identity> to pgdb compare to authenticate with an
Entra ID token instead of a static password. Which token flow is used is
auto-detected from the database hostname:
- Azure Database for PostgreSQL (
*.postgres.database.azure.com,*.postgres.cosmos.azure.com) — the default: fetches a token viaDefaultAzureCredentialand uses it directly as the password. Requires theazureextra:pip install pgdevkit[azure]. - Databricks Lakebase (
*.database.azuredatabricks.net,*.database.cloud.databricks.com) — fetches a Databricks-scoped Entra token, then exchanges it for a short-lived Postgres credential via the Databricks workspace API. Also requires--databricks-workspace-hostand--databricks-instance:
pgdb compare --url postgresql://instance-abc.database.azuredatabricks.net:5432/databricks_postgres \
--entra-user alice@example.com \
--databricks-workspace-host https://adb-123456789.azuredatabricks.net \
--databricks-instance myinstance \
path/to/database/
(--url's own user/password, if any, are discarded and replaced — --entra-user
plus the fetched token become the connection's actual credentials.)
pgdb testdb
Manages a single shared, Podman-backed Postgres container for local tests across all your projects — no more one-container-per-project-per-worktree. Isolation between projects and worktrees is per-database, inside one container.
Add to pyproject.toml:
[tool.pgdevkit]
name = "myproject" # optional; defaults to the repo directory name
database_dir = "database" # optional; defaults to "database"
Add to conftest.py:
import os
import pytest
from pgdevkit.testdb import ensure_testdb
@pytest.fixture(scope="session", autouse=True)
def ensure_test_postgres():
for k, v in ensure_testdb().items():
os.environ[k] = v
CLI: pgdb testdb up|reset|run-sql|status|shell|clean.
Container connection defaults (localhost:54322, postgres/testpwd) can
be overridden with PGDEVKIT_TESTDB_HOST, PGDEVKIT_TESTDB_PORT,
PGDEVKIT_TESTDB_USER, PGDEVKIT_TESTDB_PASSWORD. Before touching the
Docker API, pgdevkit first checks (with a short timeout) whether Postgres
is already reachable at that address and skips container management if so.
Set PGDEVKIT_SKIP_CONTAINER=1 to always assume it's already there and skip
that check too.
Container management goes through the Docker API (the docker package,
docker.from_env(), falling back to Podman's rootful/rootless socket) — it
works against a real Docker daemon or Podman transparently, no CLI binary
required either way.
To point at a local Postgres install instead of the container — useful when
neither is available, or you'd rather use peer authentication as the
current OS user — set PGDEVKIT_TESTDB_HOST to the unix socket
directory (e.g. /var/run/postgresql) and PGDEVKIT_TESTDB_PASSWORD="".
The role named by PGDEVKIT_TESTDB_USER must exist and match your OS user
(CREATE ROLE <user> SUPERUSER LOGIN;) and pg_hba.conf must allow peer
auth for local connections (Debian/Ubuntu Postgres ships this by default).
pgdevkit.db — helpers for application code
Install with the db extra: pip install pgdevkit[db].
PostgresTableModel— apydantic.BaseModelbase class for models that map 1:1 to a table row. Implementget_table_name()(returns(schema, table)) andget_primary_key()on each model.PgPool— an async connection pool keyed off{env_prefix}HOST/PORT/DB/USER/PASSWORDenv vars. Callawait pool.open()once at startup, then useasync with pool.connection() as con:. Passentra_userto authenticate via Entra ID instead of a static password — same host-based auto-detection aspgdb compare's--entra-user. For Lakebase hosts, also set the{env_prefix}DATABRICKS_WORKSPACE_HOSTand{env_prefix}DATABRICKS_INSTANCEenv vars.- CRUD functions —
pg_retrieve,pg_retrieve_many,pg_insert,pg_insert_many,pg_update,pg_update_dict,pg_upsert,pg_upsert_dict,pg_upsert_many,pg_upsert_many_dict,pg_delete,pg_delete_dict— typed (PostgresTableModel-based) or dict-based CRUD against a table, built onpsycopgfor safe identifier/value handling. SqlLoader— loads and caches.sqlfiles from{root}/<topic>/<name>.sql, for keeping hand-written queries out of Python source.
from pgdevkit.db import PgPool, PostgresTableModel, pg_retrieve, pg_upsert
class Widget(PostgresTableModel):
id: int
name: str
@staticmethod
def get_table_name() -> tuple[str, str]:
return ("public", "widget")
@staticmethod
def get_primary_key() -> list[str]:
return ["id"]
pool = PgPool(env_prefix="POSTGRES_")
await pool.open()
async with pool.connection() as con:
widget = await pg_retrieve(con, Widget, {"id": 1})
await pg_upsert(con, Widget(id=1, name="thing"), Widget)
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
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 pgdevkit-0.2.4.tar.gz.
File metadata
- Download URL: pgdevkit-0.2.4.tar.gz
- Upload date:
- Size: 82.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fe35b58bf43c8bfe52b909a9bcb2a4eee4ff23243a25e725d0dcef2e7496f27d
|
|
| MD5 |
56814e55bda03c9d169c702df67d285d
|
|
| BLAKE2b-256 |
c514a6909f91241365b766f4e42c1194206cfd4eebada2b48355737350f40932
|
Provenance
The following attestation bundles were made for pgdevkit-0.2.4.tar.gz:
Publisher:
python-publish.yml on bmsuisse/pgdevkit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pgdevkit-0.2.4.tar.gz -
Subject digest:
fe35b58bf43c8bfe52b909a9bcb2a4eee4ff23243a25e725d0dcef2e7496f27d - Sigstore transparency entry: 2190399651
- Sigstore integration time:
-
Permalink:
bmsuisse/pgdevkit@a353f702fc304e7ffb24a65b8dc8ae151f195bae -
Branch / Tag:
refs/tags/v0.2.4 - Owner: https://github.com/bmsuisse
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@a353f702fc304e7ffb24a65b8dc8ae151f195bae -
Trigger Event:
release
-
Statement type:
File details
Details for the file pgdevkit-0.2.4-py3-none-any.whl.
File metadata
- Download URL: pgdevkit-0.2.4-py3-none-any.whl
- Upload date:
- Size: 51.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5f5f37a21b338c2d2ec8543ac59d69bd7f8d1f4dfe48cb86abf1340a6e50bad5
|
|
| MD5 |
6fd391fc8c22e6611800947b65107ed0
|
|
| BLAKE2b-256 |
987d0d42857e15886839cce9e2c3ecd2376f34a4fa1c0a8a51bccb093b81ae0b
|
Provenance
The following attestation bundles were made for pgdevkit-0.2.4-py3-none-any.whl:
Publisher:
python-publish.yml on bmsuisse/pgdevkit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pgdevkit-0.2.4-py3-none-any.whl -
Subject digest:
5f5f37a21b338c2d2ec8543ac59d69bd7f8d1f4dfe48cb86abf1340a6e50bad5 - Sigstore transparency entry: 2190399829
- Sigstore integration time:
-
Permalink:
bmsuisse/pgdevkit@a353f702fc304e7ffb24a65b8dc8ae151f195bae -
Branch / Tag:
refs/tags/v0.2.4 - Owner: https://github.com/bmsuisse
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@a353f702fc304e7ffb24a65b8dc8ae151f195bae -
Trigger Event:
release
-
Statement type: