Skip to content

feat(cli): resolve PostgreSQL settings from app.yaml, not just env - #143

Merged
eldonm merged 3 commits into
mainfrom
feat/postgres-config-passthrough
Aug 8, 2026
Merged

feat(cli): resolve PostgreSQL settings from app.yaml, not just env#143
eldonm merged 3 commits into
mainfrom
feat/postgres-config-passthrough

Conversation

@eldonm

@eldonm eldonm commented Aug 7, 2026

Copy link
Copy Markdown
Member

Summary

create_server_from_config threads mongodb's uri/name and dynamodb's table/region into jvspatial's DatabaseConfig — but had nothing for postgres. The DSN reached the driver only through jvspatial's own env read, so an app.yaml database.uri was silently ignored for postgres while working for every other backend.

This wires the four postgres_* settings through, and bumps the pin to jvspatial==0.0.17.

Related issues

Depends on TrueSelph/jvspatial#37, released in 0.0.17 (now on PyPI). Completes the Postgres work from #139 / #140.

Type of change

  • Bug fix (non-breaking)
  • New feature (non-breaking) — app.yaml now configures Postgres
  • Breaking change
  • Documentation
  • Chore / tooling / CI — pin bump

Changes

File Change
jvagent/cli/server_config.py database.uri / pooler_mode / min_pool_size / max_pool_sizeDatabaseConfig for postgres/postgresql
tests/cli/test_server_config_postgres.py new — 7 tests
pyproject.toml pin 0.0.160.0.17
docs/postgres.md caveat replaced with a worked app.yaml example
.env.example, environment-keys-reference.md notes corrected
.planning/reference/jvspatial-integration.md pin refs §1 and §5
CHANGELOG.md [Unreleased] entry

Checklist

  • I read CONTRIBUTING.md and the local jvagent/cli/CLAUDE.md.
  • pre-commit run --all-files passes.
  • pytest tests/ passes — 0 failures, run against the released 0.0.17 wheel.
  • Bug fixes cite file:line in the description.
  • Docs / CHANGELOG.md updated.
  • No ADR was modified in place.

Notes for reviewers

Why the pin has to move. Before 0.0.17, DatabaseConfig discarded anything passed by field name — its aliased fields lacked populate_by_name, so DatabaseConfig(postgres_dsn=...) silently produced None. This passthrough would have been written correctly and done nothing. That is in fact how the upstream bug was found: the code looked right and the tests failed. Worth knowing because the same shape was also silently breaking DynamoDB's app.yaml config, for as long as those fields have existed.

Shared database.uri. Postgres reads the same app.yaml key as mongodb, with database.type deciding interpretation. The alternative was a database.postgres_uri, which would have made the stanza backend-specific in a way the existing keys are not. Easy to change if you'd rather they were distinct.

A typo shouldn't stop the server booting. A non-integer pool size is logged and dropped rather than raised, so the driver default applies. Covered by test_non_integer_pool_size_is_ignored.

Verified against the released wheel, not a checkout. pip install jvspatial==0.0.17 from PyPI: full suite 0 failures, and scripts/smoke_postgres.sh 15/15 — bootstrap, serve, JWT login, agent turn, server restart, and recall of pre-restart state from Postgres.

One process note: my first verification of this branch failed, because uv pip install -e with a relative --python path installed into the sibling repo's venv instead of this one, and import jvspatial; print(jvspatial.__file__) reported the source path anyway due to cwd shadowing. If you verify locally, check the specific module — python -c "import jvspatial.api.config_groups as cg; print(cg.__file__)" — which is unambiguous.

Steps to test

pytest tests/cli/test_server_config_postgres.py -q
scripts/smoke_postgres.sh          # spins up its own container

For the new path specifically, an app.yaml with no JVSPATIAL_POSTGRES_* env set:

config:
  database:
    type: postgres
    uri: postgresql://user:pw@localhost:5432/mydb
    pooler_mode: transaction

Eldon Marks added 2 commits August 7, 2026 10:34
create_server_from_config built an explicit DatabaseConfig with mongodb's
uri/name and dynamodb's table/region, but nothing for postgres. The DSN
reached the driver only through jvspatial's own env read, so an app.yaml
database.uri was silently ignored for postgres while working for every
other backend -- the one case where a documented config path did nothing.

Thread database.uri / pooler_mode / min_pool_size / max_pool_size through
for postgres and postgresql. database.uri is shared with mongodb;
database.type decides how it is read. Unset values stay None so
PostgresDB's own defaults still apply, and a non-integer pool size is
logged and ignored rather than failing startup -- a typo'd pool size
should not stop a server from booting.

Requires jvspatial 0.0.17. Until then DatabaseConfig discarded anything
passed by field name (its aliased fields lacked populate_by_name), so
this passthrough would have been written correctly and done nothing --
which is how that upstream bug was found. Pin bumped.

Verified against the released 0.0.17 wheel, not a local checkout: full
suite green, and scripts/smoke_postgres.sh 15/15 including recall across
a server restart.

Docs drop the "DSN is env-only" caveat and gain a worked app.yaml
example. Also refreshes two stale pin references in
jvspatial-integration.md sections 1 and 5.
The new tests build a real Server with db_type=postgres, which now
instantiates PostgresDB and imports asyncpg. asyncpg is an optional extra,
so CI did not have it and the job failed with ImportError -- while passing
locally purely because this machine had the driver installed from earlier
Postgres work. A test that depends on an undeclared extra is a test that
passes for the wrong reason.

Add asyncpg to the [test] extra so CI exercises the feature, and guard the
module with pytest.importorskip so anyone running the suite without the
extra skips instead of erroring (matching jvspatial's own postgres tests).
Verified both ways: 7 passed with the driver, cleanly skipped without it.

Also syncs requirements.txt and requirements-all.txt, which still pinned
jvspatial==0.0.15 -- stale since the 0.0.16 bump and now two releases
behind pyproject.
…passthrough

# Conflicts:
#	CHANGELOG.md
#	requirements-all.txt
#	requirements.txt
@eldonm
eldonm merged commit 05101ba into main Aug 8, 2026
3 checks passed
@eldonm
eldonm deleted the feat/postgres-config-passthrough branch August 8, 2026 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant