Assert icon
Query icon
OutputValues icon
Log icon
If icon
SlackIncomingWebhook icon
Pause icon
Loop icon
Schedule icon

Restore PostgreSQL foreign-key triggers after interrupted loads

Restore disabled PostgreSQL foreign-key triggers after interrupted loads with approval, bounded locks and an audit of existing orphan rows.

Categories
Data

How it works

Audit disabled internal FK triggers in one schema through PostgreSQL Query. Count orphan rows only for supported pairs below the size ceiling. Approval covers a bounded batch. Each DO statement locks both tables, checks the constraint and trigger snapshot again then enables only its disabled internal triggers. A separate query requires the approved constraints to exist with no disabled triggers.

What you get

A repair plan with orphan counts and a check that trigger restoration landed. Existing rows are never changed. Enabling a trigger does not validate old data.

Who it's for

Database operators recovering from a bulk loader that disabled FK triggers and exited before restoring them.

Why orchestrate this with Kestra

Keep the read-only schedule, explicit approval, bounded repairs and failed-write alert in one execution. All database work uses the native JDBC plugin.

Tested end to end

PostgreSQL 16, 20 cases on Kestra 2.0.6, six key cases on 2.0.5 and six cases on a fresh fixture. Independent psql reads confirmed two disabled FK triggers became zero while four original rows and one historic orphan survived. A new invalid origin-session insert failed afterward. Declined or omitted approval, stale data/name, insufficient privileges, lock timeout, unsupported shapes and size/scan ceilings preserved data. Retry finished a bounded partial pass.

Prerequisites

PostgreSQL 16 reachable over JDBC. Detection needs catalog and table reads. Restoring internal triggers requires superuser. Scope is immediate single-column integer MATCH SIMPLE FKs between ordinary tables in the same schema. Inheritance, partitions, RLS and other FK shapes are not changed.

Secrets

POSTGRES_USERNAME, POSTGRES_PASSWORD and SLACK_WEBHOOK_URL. Password and webhook overrides are SECRET inputs.

Inputs

Set postgres_url, schema_name and protected_constraints. max_pair_mb bounds the combined table/index size before counting rows. max_repairs bounds each batch. Safe defaults are dry_run=true and auto_remediate=false.

Quick start

  1. Configure credentials and run the safe default mode.
  2. Review unsupported pairs and intentional disables. Protect intentional constraint names.
  3. Set both live-mode inputs and approve only the displayed batch. Review old orphan rows separately.

How to extend

Add a separate data-correction workflow after reviewing orphan rows. Limits: the queue serializes this flow only. Each table pair has a two-second lock budget and a 20-second statement budget. Repairs are atomic per constraint, not per batch. Enabled triggers enforce origin/local sessions, not sessions deliberately using session_replication_role=replica. This flow does not restore that session setting or claim historical integrity.

Links

This blueprint was created by zkasuran.

See How

New to Kestra?

Use blueprints to kickstart your first workflows.