Queries icon
Loop icon
Sequential icon
Query icon
If icon
CopyIn icon
Fail icon
Log icon
Trigger icon

Idempotent Incremental CSV Loader from S3 to PostgreSQL

Poll S3 for CSV files and load file versions into PostgreSQL with a ledger, staging, validation, upserts and retry tracking.

Categories
CloudData

Overview

This blueprint polls an S3-compatible bucket for CSV files and tracks each file version in PostgreSQL. A successful version is skipped on later detections; failed versions remain eligible for retry.

How it works

  1. init_schema creates the target table and processing ledger.
  2. watch_bucket detects matching CSV objects.
  3. process_files handles each detected object sequentially.
  4. claim_file atomically claims a version identified by bucket, key, ETag and size.
  5. The CSV is copied to an isolated staging table and validated.
  6. Valid rows are upserted into public.customer_data; the ledger is marked SUCCESS in the same SQL statement.
  7. Failed processing is recorded as FAILED when the current execution still owns the claim.

Prerequisites

  • Kestra with the AWS S3 and PostgreSQL plugins available.
  • PostgreSQL and an S3-compatible bucket with list/read access.
  • A database user allowed to create and drop tables in the public schema.

Secrets

Configure POSTGRES_JDBC_URL, POSTGRES_USERNAME, POSTGRES_PASSWORD, AWS_ACCESS_KEY_ID, and AWS_SECRET_KEY_ID in Kestra.

CSV format

The CSV must contain a header row with customer_id,name,email,city. The required data fields are customer_id, name, and email. Repeated customer IDs within one file resolve to the last row. Across different files, the most recently processed file can update an existing customer.

Local testing

For MinIO, set s3_endpoint to the MinIO service URL reachable from the Kestra container and use MinIO credentials as the S3 secrets. Create the incoming-data bucket and upload a CSV such as:

customer_id,name,email,city
C001,Asha Rao,asha@example.com,Mumbai
C002,Ben Lee,ben@example.com,Pune

Test a first load, a repeated detection of the same object version, an invalid CSV, and a retry after a failed load. Confirm the target table and ledger directly in PostgreSQL.

Important limitations

ETag plus object size is a practical version key, but an ETag is not guaranteed to be a content hash for every S3 upload/encryption mode. This blueprint's retry behavior also depends on the trigger detecting the object again or an operator replaying the execution. Validate trigger state and plugin properties against the Kestra version used for deployment.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.