PostgreSQL testing¶
The PostgreSQL arm is optional. Start a local server with the helper target and export the test URI it prints:
make postgres-dev-server
export HTTK_TEST_POSTGRES_URI='postgresql+psycopg://postgres:postgres@127.0.0.1:5432/httk'
The helper runs the pinned postgres:16 image as a detached container named
httk-postgres on the host network, with POSTGRES_PASSWORD=postgres and the
httk database, waits for pg_isready, and prints the URI to export. Stop it
with make postgres-stop. A raw equivalent is:
docker run --detach --name httk-postgres --network host \
-e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=httk postgres:16
Any reachable PostgreSQL server works; only the URI matters.
The driver requirement¶
Backend.postgresql() supports the psycopg 3 driver only. A bare
postgresql:// URL is normalized to postgresql+psycopg:// (SQLAlchemy 2.0
would otherwise select psycopg2), and any other explicit driver is rejected.
Install the client with the postgresql extra, which pins psycopg 3:
python -m pip install "httk-store[postgresql]"
CI installs .[dev,postgresql,parallel]; there is no committed constraints
file for PostgreSQL, so the pyproject.toml extra range applies directly.
Skipping when unset¶
HTTK_TEST_POSTGRES_URI must name a reachable admin URI (used to create and
drop a fresh isolated database per test). When it is unset every PostgreSQL
test skips with a pointer to this setup, so the default suite stays green
without a server. The parameterized backend suites add PostgreSQL under the
postgres xdist group so its per-test databases do not collide.
Known limitation¶
Under PostgreSQL bulk ingest, a NaN inside a stored list-of-floats
(child) field is not preserved — it reads back as NULL. Bulk ingest stages
rows through SQLite shards, and SQLite has no NaN, so the value is lost in the
list column. A scalar float NaN IS preserved under bulk ingest, and the
serial save() path preserves NaN in both scalar and list fields on all
backends. See the database backend details.