New to Kestra?
Use blueprints to kickstart your first workflows.
Extract a CSV over HTTP and bulk load it into an Oracle staging table with Kestra. Truncate-and-reload with named-column JDBC batches, then assert the row count.
Load CSV data into Oracle Database on a reliable, re-run-safe schedule. This blueprint extracts a CSV over HTTP, bulk inserts it into an Oracle staging table with named-column JDBC batches, and asserts the row count before declaring success, giving you a verified Oracle ETL pipeline for orders, reference data, or any flat-file feed without hand-written load scripts.
download_csv (io.kestra.plugin.core.http.Download) pulls the source CSV from the HTTP(S) endpoint in inputs.source_url into Kestra internal storage, with a constant retry on transient network failures.csv_to_ion (io.kestra.plugin.serdes.csv.CsvToIon) converts the CSV into the ION format the Oracle Batch task consumes.create_table (io.kestra.plugin.jdbc.oracle.Query) runs idempotent DDL to create the staging table, swallowing ORA-00955 (name already used) so re-runs are safe.truncate_staging (io.kestra.plugin.jdbc.oracle.Query) truncates the table so a re-run or backfill reloads cleanly instead of doubling rows.bulk_insert (io.kestra.plugin.jdbc.oracle.Batch) inserts the rows using prepared-statement batches with chunk: 1000 and explicit named columns.verify_load (io.kestra.plugin.jdbc.oracle.Query with fetchType: FETCH_ONE) reads the row count back, and assert_load (io.kestra.plugin.core.execution.Assert) fails the run if zero rows landed or the count does not match the inserted count.log_summary (io.kestra.plugin.core.log.Log) surfaces rows read versus rows inserted so a silently dropped row is obvious.concurrency.limit is 1, so two runs never interleave against the same table.errors block.Oracle has no built-in scheduler for pulling a remote file, validating the load, and alerting on failure. Kestra adds event and schedule triggers, per-task retries, an Assert gate that turns a bad load into a failed execution, full run lineage and logs, and Slack alerting, all in declarative YAML. The truncate-first design plus concurrency.limit makes every run reproducible in a way a cron-driven SQL script cannot guarantee.
jdbc:oracle:thin:@//host:1521/service.CREATE TABLE, TRUNCATE, and INSERT privileges on the target schema.ORACLE_USERNAME: the Oracle user used for the DDL, truncate, bulk insert, and verification query.ORACLE_PASSWORD: the password for that Oracle user.SLACK_WEBHOOK: the Slack Incoming Webhook URL the failure alert is posted to.ORACLE_USERNAME, ORACLE_PASSWORD, and SLACK_WEBHOOK secrets.oracle_url variable to point at your instance and service name.source_url input or add a table name to the target_table allow-list (keep the column list in the DDL, columns, and INSERT aligned with your CSV).Note on the table name: target_table is a SELECT input restricted to an allow-list, not free-text. Oracle cannot bind a table identifier as a parameter, so the name is concatenated into the DDL, TRUNCATE, and INSERT. Keeping it an enum makes that concatenation safe, so only operator-trusted names should be added to the values list.
Schedule trigger to run the load nightly, or an event trigger to fire when a new file arrives.source_url at S3, GCS, or an SFTP-fronted endpoint, or swap Download for a storage-specific task.Query task, or branch into dbt.target_table allow-list and column mapping to cover more feeds.