Skip to content

0003. Connettore Postgres basato su pg + pg-cursor

  • Stato: Accettata
  • Data: 2026-06-03
  • Decisori: Team BI/ETL

Contesto

Serve il primo connettore reale verso un database relazionale (PostgreSQL), sia in estrazione (Source) sia in caricamento (Sink). Requisiti dalle nostre convenzioni: streaming (no result-set interi in memoria), idempotenza del caricamento, niente any, niente segreti hardcoded.

Decisione

Adottiamo pg (driver PostgreSQL de-facto per Node) e pg-cursor per lo streaming server-side dell'estrazione.

  • postgresSource usa un cursor e legge a batch (AsyncIterable).
  • postgresSink esegue INSERT ... ON CONFLICT DO UPDATE in batch dentro una transazione → upsert idempotente sulla chiave naturale.
  • Il Pool è iniettato dal chiamante (DI): il connettore non possiede il ciclo di vita della connessione, facilitando test e riuso.
  • pg-cursor non ha tipi: forniamo una dichiarazione ambient minimale (src/connectors/postgres/pg-cursor.d.ts) per restare strict senza any.

Alternative considerate

  • postgres (porsager) — ottimo e moderno, ma pg è più diffuso, stabile e con tipi maturi.
  • ORM (Prisma/Drizzle) — troppo per un connettore ETL low-level; aggiungono generazione di schema e overhead non necessari qui.
  • Paginazione LIMIT/OFFSET invece del cursor — semplice ma inefficiente su grandi offset e richiede un ordinamento stabile; il cursor server-side è più adatto allo streaming.

Conseguenze

  • Positive: streaming reale, upsert idempotente, API piccola e tipata, DI testabile.
  • Costi: manteniamo una piccola dichiarazione di tipi per pg-cursor.
  • I file I/O del connettore (source.ts, sink.ts) sono coperti dai test di integrazione (pnpm run test:integration), non dalla suite unitaria in CI; la logica pura (query.ts, config.ts) resta coperta al 100% e inclusa nel gate di coverage.

Noeva è un marchio registrato di 4D S.R.L.