Skip to content

Postgres

pip install "dataveil[postgres]"
import sqlalchemy as sa
from dataveil.adapters.postgres import PostgresAdapter

adapter = PostgresAdapter(sa.create_engine("postgresql+psycopg2://localhost/analytics"))

A plain SQLAlchemy Engine against real tables. The Luhn and IBAN checksum functions are written in PL/pgSQL rather than Python, because most managed Postgres instances do not allow Python functions. So every regex and checksum classifier works. The person-name classifier needs Python inside the engine, so it is skipped on Postgres.

parse_date takes Python strftime-style formats (%Y-%m-%d), like the other adapters, and the adapter translates the common tokens to Postgres's to_char/to_timestamp patterns.

Building the Postgres adapter is what caught two real dialect-coupling bugs in core/: classify.py was built against DuckDB's regexp_matches() returning a boolean, which doesn't hold on Postgres (there it's a set-returning function and can't go inside FILTER) — fixed by switching to the POSIX ~ match operator, which both engines support as a boolean predicate. profile.py used DuckDB's QUANTILE_CONT(col, frac) shorthand — fixed by switching to the ANSI-standard PERCENTILE_CONT(frac) WITHIN GROUP (ORDER BY col), which both support. Exactly the kind of bug a second adapter is supposed to surface.

With the MCP server: DATAVEIL_ADAPTER=postgres and DATAVEIL_POSTGRES_URL.