Skip to content

Ingestr Assets

Ingestr is a CLI tool that allows you to move data between platforms. Bruin supports ingestr natively as an asset type.

Using Ingestr, you can move data from:

  • your production databases like:
    • MSSQL
    • MySQL
    • Oracle
  • your daily tools like:
    • Notion
    • Google Sheets
    • Airtable
  • from other platforms such as:
    • Hubspot
    • Salesforce
    • Google Analytics
    • Facebook Ads
    • Google Ads

to your data warehouses:

  • AWS Athena
  • Google BigQuery
  • ClickHouse
  • Databricks
  • DuckDB
  • Microsoft SQL Server
  • Oracle
  • Postgres
  • StarRocks
  • Snowflake
  • AWS Redshift
  • Azure Synapse
  • other ingestr destinations when the asset points at an explicit Bruin connection

INFO

See the ingestr platform catalog, ingest command reference, and incremental loading guide for the upstream source, destination, and strategy behavior.

Asset Structure

yaml
name: string
type: ingestr
connection: string # optional, by default uses the default connection for destination platform in pipeline.yml
materialization: # optional, preferred for destination write strategy
  type: table
  strategy: create+replace | append | merge | delete+insert | truncate+insert
  incremental_key: string
  partition_by: string
  cluster_by:
    - string
parameters:
  source: string # optional, used when inferring the source from connection is not enough, e.g. GCP connection + GSheets source
  source_connection: string
  source_table: string
  destination: string # logical destination type; required unless connection or destination_connection is set
  destination_connection: string # optional, used instead of destination default connection when connection is not set
  
  # optional
  version: v0 | v1 | vMAJOR.MINOR.PATCH
  incremental_strategy: replace | append | merge | delete+insert | truncate+insert # legacy alternative to materialization.strategy
  incremental_key: string # legacy alternative to materialization.incremental_key
  schema_contract: evolve | freeze | discard_row | discard_value
  schema_naming: auto | default | direct | snake_case
  sql_backend: pyarrow | sqlalchemy
  page_size: integer
  loader_file_format: jsonl | csv | parquet
  loader_file_size: integer
  extract_parallelism: integer
  extract_partition_by: string
  extract_partition_interval: string | integer
  sql_limit: integer
  sql_exclude_columns: string
  no_inference: true|false
  mask: string
  trim_whitespace: true|false
  pipelines_dir: string
  staging_bucket: string
  staging_dataset: string
  stream: true|false
  flush_interval: string
  flush_records: integer
  enforce_schema: true|false # Will ensure that the columns defined in the asset are present in the destination and with the desired types (see https://getbruin.com/docs/bruin/assets/columns.html)
  cdc: "true"|"false"
  cdc_mode: stream | batch # deprecated, use stream instead
  cdc_sql_capture: cdc | change_tracking
  cdc_publication: string
  cdc_slot: string
  cdc_server_id: string
  cdc_tls: string
  cdc_grpc_port: string
  cdc_grpc_host: string
  cdc_grpc_tls: string
  cdc_capture_instance: string
  cdc_poll_interval: string
  cdc_max_await_time: string
  cdc_schema_sample_size: integer
  cdc_dest_schema: string
  cdc_state_id: string
  cdc_stream_metrics_addr: string
  cdc_stream_flush_interval: string
  cdc_stream_flush_records: integer

Parameter reference

ParameterRequiredIngestr flagDescription
connectionNo--dest-uriDestination connection; defaults to the pipeline's connection for the asset.
source_connectionYes--source-uriName of the configured source connection. Bruin resolves it to the URI passed to Ingestr.
sourceNon/aOverrides the inferred source type. For example, set gsheets when reusing a BigQuery connection for Google Sheets.
source_tableYes--source-tableTable, sheet, or resource identifier to pull from the source.
file_typeNo--source-table suffixAppended to the source_table as table#type for connectors that need a file format hint (csv, jsonl, parquet).
versionNon/aSelects the version of ingestr to install and use. Valid options are bare family markers such as v1 or v0, or a full version pin such as v1.0.71.
materializationNo--incremental-*, --partition-by, --cluster-byPreferred way to define destination write behavior. Supports type: table with create+replace, append, merge, delete+insert, and truncate+insert.
destinationUnless connection or destination_connection is setn/aLogical destination type used for default connection inference. When connection and destination_connection are omitted, Bruin uses this value to choose the pipeline default destination connection.
destination_connectionNon/aNamed destination connection to use when connection is omitted. This overrides default connection inference from destination.
incremental_strategyNo--incremental-strategyPasses the incremental loading strategy (replace, append, merge, delete+insert, or truncate+insert) to Ingestr. Prefer materialization.strategy for new assets.
incremental_keyNo--incremental-keyColumn that determines incremental progress. When the column is defined with type date, Bruin also forwards it through the --columns option so Ingestr treats it as a date field.
partition_byNo--partition-byComma-separated list of destination columns to partition by.
cluster_byNo--cluster-byComma-separated list of destination clustering keys.
schema_contractNo--schema-contractControls how Ingestr handles schema changes (evolve, freeze, discard_row, discard_value).
loader_file_formatNo--loader-file-formatOverrides the loader file format (jsonl, csv, parquet).
loader_file_sizeNo--loader-file-sizeSets the maximum loader file size accepted by Ingestr.
sql_backendNo--sql-backendSelects the SQL backend Ingestr should use (pyarrow or sqlalchemy).
schema_namingNo--schema-namingControls how Ingestr normalizes schema names. Accepted values match the Ingestr CLI.
page_sizeNo--page-sizeSets the fetch page size for SQL sources.
extract_parallelismNo--extract-parallelismLimits the number of concurrent extraction workers.
extract_partition_byNo--extract-partition-bySource date/time or integer column used to split bounded extraction into parallel windows.
extract_partition_intervalNo--extract-partition-intervalWidth of each extract partition window as a duration (such as 1h or 7d), integer step, or auto. Ingestr defaults to auto when extract_partition_by is set.
sql_reflection_levelNo--sql-reflection-levelTunes the amount of schema reflection performed against the source.
sql_limitNo--sql-limitApplies a LIMIT clause when extracting from the source.
sql_exclude_columnsNo--sql-exclude-columnsList of columns to skip during extraction.
no_inferenceNo--no-inferenceUses columns as the source schema for schema-less sources instead of inferring types.
maskNo--maskAdds a column masking rule such as email:hash.
pipelines_dirNo--pipelines-dirDirectory where Ingestr stores pipeline metadata.
staging_bucketNo--staging-bucketOverrides the staging bucket that Ingestr uses for intermediate files.
staging_datasetNo--staging-datasetDataset/schema to use for staging tables.
trim_whitespaceNo--trim-whitespaceTrims leading and trailing whitespace from extracted string values when set to true.
streamNo--streamEnables continuous ingestion. Works for CDC sources (cdc: true) and message-broker sources (such as Kafka). A streaming asset never exits on its own and must be launched with bruin run --stream (see Streaming assets).
flush_intervalNo--flush-intervalFlush interval for streaming mode, such as 30s. CDC assets can set cdc_stream_flush_interval instead, which takes precedence.
flush_recordsNo--flush-recordsNumber of buffered records that triggers a flush in streaming mode. CDC assets can set cdc_stream_flush_records instead, which takes precedence.
enforce_schemaNo--columnsWhen set to true, enforces the column types defined in the asset's columns section. Ingestr will create or update the destination table with the specified schema.
cdcNosource URI schemeEnables Bruin's CDC URI handling for PostgreSQL, MySQL/MariaDB, Vitess, PlanetScale, MongoDB, and SQL Server (log-based CDC and Change Tracking) sources when set to "true". CDC assets must use merge; Bruin sets it automatically when omitted and rejects other strategies.
cdc_modeNo--stream flagDeprecated — use stream instead. cdc_mode: stream is equivalent to stream: true; cdc_mode: batch is the default (omit it).
cdc_sql_captureNosource URI schemeSQL Server capture mechanism, either cdc (log-based, mssql+cdc; default) or change_tracking (mssql+ct).
cdc_publicationNosource URI queryPostgreSQL publication name.
cdc_slotNosource URI queryPostgreSQL replication slot name.
cdc_server_idNosource URI queryMySQL-family binlog replication server ID.
cdc_tlsNosource URI queryMySQL-family CDC TLS setting.
cdc_grpc_portNosource URI queryVitess VStream gRPC port override.
cdc_grpc_hostNosource URI queryVitess VStream gRPC host override.
cdc_grpc_tlsNosource URI queryVitess VStream TLS setting.
cdc_capture_instanceNosource URI querySQL Server log-based CDC capture instance name.
cdc_poll_intervalNosource URI querySQL Server log-based CDC poll interval, such as 10s.
cdc_max_await_timeNosource URI queryMongoDB change-stream maximum await time, such as 5s.
cdc_schema_sample_sizeNosource URI queryMongoDB number of documents sampled to infer the schema.
cdc_dest_schemaNosource URI queryDestination schema used for multi-table CDC runs.
cdc_state_idNosource URI queryStable identity for this CDC connector's resume state. Set it when multiple otherwise-identical CDC assets write to the same destination so they keep independent offsets.
cdc_stream_metrics_addrNo--metrics-addrAddress on which a streaming CDC asset serves replication lag and rows-synced metrics at /debug/vars, such as 127.0.0.1:6060. Requires stream: true. See PostgreSQL CDC.
cdc_stream_flush_intervalNo--flush-intervalFlush interval for a streaming CDC asset. Takes precedence over flush_interval.
cdc_stream_flush_recordsNo--flush-recordsBuffered record count that triggers a flush for a streaming CDC asset. Takes precedence over flush_records.

Destination connections and strategies

Bruin resolves the destination connection in this order:

  1. connection on the asset, when set.
  2. parameters.destination_connection, when set.
  3. The pipeline default connection for parameters.destination.

When Bruin infers a destination connection from parameters.destination, the built-in destination values are athena, bigquery, clickhouse, databricks, doris, duckdb, dynamodb, elasticsearch, gsheets, motherduck, mssql, oracle, postgres, redshift, snowflake, starrocks, synapse, and vertica. Other ingestr destinations can still be used when you set connection or destination_connection to a compatible Bruin connection.

Bruin forwards these write strategies to ingestr:

Bruin configurationIngestr strategy
materialization.strategy: create+replacereplace
materialization.strategy: appendappend
materialization.strategy: mergemerge
materialization.strategy: delete+insertdelete+insert
materialization.strategy: truncate+inserttruncate+insert
parameters.incremental_strategyPassed through as-is

Use materialization.incremental_key or parameters.incremental_key only with append, merge, and delete+insert. merge requires primary keys, supplied either by ingestr source metadata/schema or by asset columns marked primary_key: true; CDC assets determine keys from the source. truncate+insert is accepted by Bruin, but ingestr will fail the run if the selected destination cannot truncate tables. Ingestr's scd2 strategy is not a supported Bruin ingestr asset materialization strategy.

Destination support depends on ingestr's destination implementation:

Destination / schemeBruin can infer default connection from destinationSupported strategies in Bruin ingestr assets
Athena / athenaYesreplace, append
BigQuery / bigqueryYesreplace, append, merge, delete+insert, truncate+insert
Blob storage / s3, gcs, adls, abfs, etc.No, set connectionreplace, append
Cassandra / cassandraNo, set connectionreplace, append, merge, truncate+insert
ClickHouse / clickhouseYesreplace, append, merge, delete+insert, truncate+insert
CrateDB / cratedbNo, set connectionreplace, append, merge, truncate+insert
CSV, JSONL, Parquet / csv, jsonl, parquetNo, set connectionreplace, append
Databricks / databricksYesreplace, append, merge, delete+insert, truncate+insert
DuckDB, MotherDuck / duckdb, motherduck, mdYes for duckdb and motherduckreplace, append, merge, delete+insert, truncate+insert
DynamoDB / dynamodbYesreplace, append, merge
Elasticsearch / elasticsearchYesreplace, append
Fabric / fabricNo, set connectionreplace, append, merge, delete+insert, truncate+insert
Google Sheets / gsheetsYesreplace, append
Iceberg / iceberg, iceberg+rest, etc.No, set connectionreplace, append, merge, delete+insert, truncate+insert
MaxCompute / maxcompute, odpsNo, set connectionreplace, append, truncate+insert without primary keys
MongoDB / mongodb, mongodb+srvNo, set connectionreplace, append, merge
MS SQL Server / mssqlYesreplace, append, merge, delete+insert, truncate+insert
MySQL, Vitess, PlanetScale / mysql, vitess, ps_mysqlNo, set connectionreplace, append, merge, delete+insert, truncate+insert
OneLake / onelakeNo, set connectionreplace, append, merge, delete+insert
Oracle / oracleYesreplace, append, merge, delete+insert, truncate+insert
PostgreSQL / postgresYesreplace, append, merge, delete+insert, truncate+insert
Redshift / redshiftYesreplace, append, merge, delete+insert, truncate+insert
Snowflake / snowflakeYesreplace, append, merge, delete+insert, truncate+insert
SQLite / sqliteNo, set connectionreplace, append, merge, delete+insert, truncate+insert
StarRocks / starrocksYesreplace, append, merge
Synapse / synapseYesreplace, append, merge, delete+insert, truncate+insert
Trino / trinoNo, set connectionreplace, append, merge

For truncate+insert, ingestr truncates the target table before loading new rows. If primary keys are configured, ingestr also needs destination merge support to deduplicate rows from staging. The Bruin CLI can infer default connections for doris and vertica, but the current ingestr source does not register doris:// or vertica:// destinations; use native Bruin assets for those platforms unless your ingestr version adds destination support.

Each source-specific ingestion page in this documentation lists that source's supported tables with primary keys, incremental keys, and default incremental strategies. The upstream ingestr docs remain the source of truth for destination-specific strategy limits.

Column metadata

Define columns on the asset to enrich the metadata passed to Ingestr. Columns flagged as primary_key: true are translated into repeated --primary-key flags, columns with mask are translated into repeated --mask flags, and date-typed incremental keys automatically surface through --columns. See Column metadata for the syntax.

Custom SQL queries

For SQL sources, source_table can be a custom query by prefixing the SQL with query::

yaml
name: raw.recent_orders
type: ingestr
parameters:
  source_connection: postgres_prod
  source_table: "query:select id, customer_id, updated_at from public.orders where updated_at > :interval_start"
  destination: bigquery
  incremental_strategy: merge
  incremental_key: updated_at

columns:
  - name: id
    type: integer
    primary_key: true
  - name: updated_at
    type: timestamp

The incremental key must be returned by the query. For incremental runs, include your own timestamp filtering in the query and use Ingestr's :interval_start and :interval_end variables when needed.

Run configuration

Pipeline run options propagate to ingestr automatically:

  • When a run defines an interval start or end date, Bruin appends --interval-start and --interval-end with the resolved timestamps (including interval modifiers, when enabled).
  • Running with --full-refresh adds the --full-refresh flag to Ingestr.
  • For a streaming asset (stream: true), Bruin omits --interval-end so the live tail is not truncated, and does not pass --full-refresh.

Streaming assets

Some ingestr sources can ingest continuously and never finish on their own:

  • CDC sources (PostgreSQL, Vitess, PlanetScale) with cdc: true and stream: true.
  • Message-broker sources (Kafka, Kinesis) with stream: true.

A continuous asset does not fit a normal batch bruin run (which expects every asset to complete), so Bruin keeps streaming assets out of ordinary runs and gives them a dedicated run mode.

Launch a single streaming asset with --stream:

bash
bruin run --stream assets/my_stream.asset.yml
  • The run targets exactly one streaming asset and keeps it running in the foreground until you stop it with Ctrl+C (SIGINT/SIGTERM). Ingestr flushes buffered records and advances its offset before exiting, so the next run resumes cleanly.
  • A normal bruin run <pipeline> skips streaming assets and prints a notice; downstream assets read whatever the stream has landed so far.
  • --stream runs only the main task — column/custom checks and metadata push do not run for a stream. It cannot be combined with --downstream, --continue, --modified, --selector, --interactive, --sensor-mode, or --full-refresh.
  • Resume state (replication offset) is managed by ingestr in the destination's staging namespace. For CDC assets it is keyed by cdc_state_id. Bruin does not store offsets.
  • For CDC assets, merge applies updates and deletes correctly only when the source table has a usable primary key / replica identity. For PostgreSQL, an unconsumed replication slot retains WAL on the source, so monitor replication lag via cdc_stream_metrics_addr (/debug/vars). See PostgreSQL CDC.

Examples

The examples below show how to use the ingestr asset type in your pipeline. Feel free to change them as you wish according to your needs.

Copy a table from MySQL to BigQuery

yaml
name: raw.transactions
type: ingestr
parameters:
  source_connection: mysql_prod
  source_table: public.transactions
  destination: bigquery

Copy a table from Microsoft SQL Server to Snowflake incrementally

This example shows how to use updated_at column to incrementally load the data from Microsoft SQL Server to Snowflake.

yaml
name: raw.transactions
type: ingestr
parameters:
  source_connection: mssql_prod
  source_table: dbo.transactions
  destination: snowflake
materialization:
  type: table
  strategy: append
  incremental_key: updated_at

Copy data from Google Sheets to Snowflake

This example shows how to copy data from Google Sheets into your Snowflake database

yaml
name: raw.manual_orders
type: ingestr
parameters:
  source: gsheets
  source_connection: gcp-default
  source_table: <mysheetid>.<sheetname>
  destination: snowflake

Enforce schema with column types

This example shows how to use enforce_schema to ensure the destination table has the correct column types. This is useful when the source system's type inference doesn't match your requirements.

yaml
name: raw.users
type: ingestr
parameters:
  source_connection: mongodb_prod
  source_table: prod.users
  destination: bigquery
  enforce_schema: true
materialization:
  type: table
  strategy: merge
  incremental_key: updated_at

columns:
  - name: _id
    type: string
    primary_key: true
  - name: name
    type: string
  - name: email
    type: string
    mask: hash
  - name: age
    type: integer
  - name: created_at
    type: timestamp
  - name: updated_at
    type: timestamp

When enforce_schema: true is set, Bruin passes the column type hints to Ingestr via the --columns flag, ensuring the destination table schema matches your definition.

Sized string types

You can give a string column an optional length to create a bounded column instead of an unbounded one. Set the length inline in the type or with the length field (requires enforce_schema: true):

yaml
parameters:
  enforce_schema: "true"

columns:
  - name: name
    type: varchar(100)
  - name: email
    type: string
    length: 255

If you set both, the inline length wins. A string type without a length creates an unbounded column.