New to Kestra?
Use blueprints to kickstart your first workflows.
Run a transactional, idempotent SAP HANA partition reload with scoped staging and a meaningful row-count verification gate, orchestrated in Kestra.
This blueprint runs a transactional, idempotent in-database ETL on SAP HANA that fully reloads a single date partition on every execution. It stages raw orders for the load date, performs a delete-then-insert on the fact partition, cleans up scoped staging, and then verifies that source and target row counts agree before the run is declared successful. Pushing the multi-statement transform into HANA keeps heavy joins next to the in-memory column store, while Kestra owns atomicity, scheduling, retries, alerting, and a data-quality gate. The delete-then-insert per partition is what makes the load idempotent: re-runs and backfills produce identical results, and rows deleted at source for a date are removed from the fact table too. It solves the classic SAP HANA ETL problem of partial writes and silent drift when a multi-step load is run by a bare scheduler with no transaction boundary or verification.
nightly_load io.kestra.plugin.core.trigger.Schedule trigger fires at 0 2 * * * in Etc/UTC.
The load_date input defaults to {{ (trigger.date ?? execution.startDate) }}, so a manual run or
backfill reloads exactly that day's partition.transform_etl task (io.kestra.plugin.jdbc.hana.Queries) runs five statements in one atomic
transaction (transaction: true): clear staging for the load date, stage raw rows, delete the fact
partition, re-insert it from staging, then clear staging again. Any statement failure rolls back the
whole transaction. A constant retry (PT1M, maxAttempt: 3) absorbs transient HANA blips.verify_row_counts task (io.kestra.plugin.jdbc.hana.Query, fetchType: FETCH_ONE) returns the
raw ingest count and the fact count for the load date in a single row.assert_counts_match task (io.kestra.plugin.core.flow.If) compares RAW_COUNT to FACT_COUNT:
a match logs success via io.kestra.plugin.core.log.Log, a mismatch fails the run with
io.kestra.plugin.core.execution.Fail and an explicit message.errors block posts a Slack alert through
io.kestra.plugin.slack.notifications.SlackIncomingWebhook with the execution id.concurrency: { limit: 1 } so two nightly loads never overlap or interleave staging.A database scheduler can run SQL on a cron, but it cannot gate the run on a data-quality check, fail the pipeline on count drift, retry only the transient failures, alert Slack with execution context, or give you per-execution lineage and replayable history. Kestra wraps the in-database transform in declarative YAML with event and schedule triggers, retries, conditional branching, and end-to-end observability, the exact gap SAP HANA's own SQL scheduler cannot fill.
databaseName for your tenant). The HANA JDBC driver (ngdbc) ships with the Kestra JDBC plugin.RAW.ORDERS_INGEST, STAGING.ORDERS_STG, and WAREHOUSE.FACT_ORDERS (or your equivalents),
each with an ORDER_DATE column.HANA_HOST: hostname or IP of the SAP HANA server.HANA_USERNAME: SAP HANA database user with read and write access to the ETL schemas.HANA_PASSWORD: password for that database user.SLACK_WEBHOOK: Slack Incoming Webhook URL for failure alerts.load_date to validate the reload and the count gate.0 2 * * * schedule run it, and confirm Slack alerts route correctly.MERGE INTO WAREHOUSE.FACT_ORDERS ... ON target.ORDER_ID = source.ORDER_ID when you must preserve fact rows absent from the current raw batch, and verify with a
checksum or EXCEPT instead of a count.assert_counts_match gate.