Skip to main content
Each row becomes one bucket object. The same connection also backs the sql_lookup retriever stage.

Overview

A PostgreSQL connection serves two paths:
  • Sync. Rows from a table land in a bucket as JSON objects, with incremental sync via a watermark column.
  • Lookup. The sql_lookup retriever stage enriches documents mid-pipeline.

Prerequisites

  • PostgreSQL 12 or later.
  • A role with CONNECT on the database and USAGE on the schema.
  • SELECT on every table you sync or query.
  • Network access from Mixpeek to the server.

Configuration

Connection-level fields

Sync-level fields

source_path accepts one or two dot-separated parts. Three or more returns a validation error.

Setup

1

Create a read-only role

2

Create the storage connection

3

Sync a table

Incremental sync

Set incremental_column to a TIMESTAMP or DATE column. Mixpeek records the highest value it has read and filters the next run to rows above it. Set primary_key_columns so object IDs stay stable across runs. Without it, a re-read can create a second object for the same row.

Bulk import and change capture

For a large table, or one with an embedding column, set provider_filters.import on the sync. The table is read in primary-key slices, each slice lands in the bucket as one Parquet object, and every row becomes one document in the collection. Each document’s ID derives from the source table and primary key, so a re-run, a resumed import or a later change updates the same document.
Customer columns keep their names in the document. Mixpeek’s own fields, including the source row’s lineage (schema, table, primary key and vector origin), live under _internal. A carried vector is refused at sync create when its model or dimension differs from the collection’s feature, or when the model has no registered query-time model, because its documents could not be searched by text. Tables without a vector column can import into a passthrough collection.

Change capture

With replication: logical, the import creates a logical replication slot first and copies every slice inside the slot’s exported snapshot. After the copy, each sync run streams the changes committed since, writes them as one change object, and confirms the slot position only after that object’s documents are written. Inserts, updates and deletes all reach the collection. Logical replication needs:
  • wal_level = logical on the server.
  • A role with the REPLICATION attribute, connecting directly to Postgres. Transaction pooling (PgBouncer in transaction mode) cannot carry a replication connection.
  • A publication that includes the table, created by the table owner:
A slot keeps WAL on your server until Mixpeek confirms it. Set max_slot_wal_keep_size so a stalled consumer cannot fill the disk, and watch the slot-lag alert on the sync record. Deleting the sync drops its slot. replication: polling reads rows whose updated_at (or updated_at_column) moved past the last value seen. It needs no replication role, and it misses hard deletes: a row deleted at the source stays in the collection. Every session that reads rows runs with default_transaction_read_only = on, so the connection cannot write to your database. The replication slot is the only object the import creates on the source.

SQL Lookup stage

Enrich documents from a SQL source inside a retriever.

Snowflake

Warehouse connection with the same two paths.