Documentation / Guides / PostgreSQL
Publish terminal results to PostgreSQL¶
Result publication happens after Closure. A slow or failed database cannot delay or rewrite the completed call.
Install and migrate¶
Select the postgres extra in the authenticated, exact-pinned
runtime install.
Apply the migration packaged inside the installed distribution under your deployment's normal migration control. The corresponding source-checkout paths are:
src/vaani/publishers/migrations/postgres/v1.sqlsrc/vaani/publishers/migrations/postgres/manifest.json
Do not let the bot process create or mutate schemas at call time.
Create a canonical publication¶
This partial application excerpt assumes an existing terminal result and an
explicit database_credentials source:
from datetime import UTC, datetime
from vaani import DeliveryPolicy, ResultPublicationRecord
from vaani.publishers.postgres import (
PostgresPublisherConfig,
PostgresResultPublisher,
)
record = ResultPublicationRecord(
idempotency_key=f"call-result:{result.call_id}",
call_id=result.call_id,
result_schema_version=result.provenance.result_schema_version,
result_digest=result.result_digest(),
canonical_result_bytes=result.canonical_bytes(),
published_at=datetime.now(UTC),
)
publisher = PostgresResultPublisher(
PostgresPublisherConfig(
sink_id="analytics-primary",
table_name="vaani_call_results",
credential_source=database_credentials,
)
)
report = await publisher.publish(
record,
DeliveryPolicy(timeout_seconds=30, max_attempts=2),
)
The credential source may resolve an explicit SQLAlchemy-compatible PostgreSQL
URL (for example from a consumer-owned DATABASE_URL) or a supported backend.
VAANI itself does not read DATABASE_URL.
Idempotency and uncertainty¶
Reuse the same idempotency key for the same canonical bytes. A conflicting
digest/bytes pair returns CONFLICT; it must not overwrite prior evidence.
Timeout or an unknown commit outcome is not permission to manufacture a success
record.
DeliveryReport is separate from CallResult and normalizes success, failure,
timeout, cancellation, or conflict. Send publisher metrics to operations
without embedding database diagnostics or credentials in call evidence.
This construction example is not a live database-success claim. Prove publication with a bounded credentialed smoke in the target environment.