sling-cli

star 6

Use when moving data between databases, files, or APIs with the sling CLI; configuring connections, writing replication YAML, running data pipelines, or troubleshooting sling run/conns commands

wenerme By wenerme schedule Updated 4/10/2026

name: sling-cli description: Use when moving data between databases, files, or APIs with the sling CLI; configuring connections, writing replication YAML, running data pipelines, or troubleshooting sling run/conns commands

Sling CLI Guide

You are a data integration expert. Use these patterns when working with the sling CLI for ETL/ELT tasks across databases, cloud storage, and APIs.

Install

# macOS
brew install slingdata-io/tap/sling

# Linux / script
curl -LO 'https://github.com/slingdata-io/sling-cli/releases/latest/download/sling_linux_amd64.tar.gz'
tar xf sling_linux_amd64.tar.gz && mv sling /usr/local/bin/

sling update   # upgrade to latest

Key Commands

# Ad-hoc data copy
sling run --src-conn PG_DB --src-stream public.users \
          --tgt-conn MYSQL_DB --tgt-object mysql.users \
          --mode full-refresh

# Run replication config file
sling run -r replication.yaml

# Run pipeline config file
sling run -p pipeline.yaml

# Debug mode
sling run -d -r replication.yaml

Connection Management

# List connections
sling conns list

# Set connection (saved to ~/.sling/env.yaml)
sling conns set MY_PG url='postgresql://user:pass@host:5432/db'
sling conns set MY_S3 type=s3 bucket=my-bucket access_key_id=KEY secret_access_key=SECRET

# Test connection
sling conns test MY_PG

# Discover available streams (tables/files/endpoints)
sling conns discover MY_PG
sling conns discover MY_PG --pattern 'public.*' --columns

# Execute SQL
sling conns exec MY_PG "select count(*) from public.users"

# Remove connection
sling conns unset MY_PG

Connection Config (~/.sling/env.yaml)

connections:
  MY_POSTGRES:
    type: postgres
    host: localhost
    user: myuser
    database: mydb
    password: ${PG_PASSWORD}
    port: 5432

  MY_S3:
    type: s3
    bucket: my-bucket
    access_key_id: ${AWS_ACCESS_KEY_ID}
    secret_access_key: ${AWS_SECRET_ACCESS_KEY}

  MY_SNOWFLAKE:
    type: snowflake
    account: myaccount
    user: myuser
    password: ${SF_PASSWORD}
    database: mydb
    warehouse: compute_wh
    schema: public

Connections can also be set via env vars:

export MY_POSTGRES='postgresql://user:pass@host:5432/db'
export MY_S3='{type: s3, bucket: my-bucket, access_key_id: KEY, secret_access_key: SECRET}'

See references/connections.md for all 40+ supported connection types.

Replication YAML

source: MY_POSTGRES
target: MY_SNOWFLAKE

defaults:
  mode: full-refresh
  target_options:
    add_new_columns: true

streams:
  # Simple full-refresh
  public.users: {}

  # Incremental by update_key
  public.orders:
    mode: incremental
    primary_key: [id]
    update_key: updated_at
    object: analytics.orders

  # Custom SQL
  public.events:
    sql: "SELECT * FROM public.events WHERE created_at > '{state.last_run_timestamp}'"
    mode: incremental
    update_key: created_at

  # Wildcard (each table → separate target)
  public.*:
    mode: full-refresh

  # Files
  file://data/*.csv:
    object: raw.csv_data
    mode: snapshot

Modes

Mode Behavior
full-refresh Drop + recreate target table, load all data (default)
incremental Load only new/changed rows via update_key
truncate Truncate target then insert all rows
snapshot Insert all rows, add _sling_loaded_at metadata
backfill Historical load with range chunking
definition-only Create table schema only, no data
change-capture CDC mode (DB→DB only)

Auto-detect: If primary_key or update_key present → incremental, else → full-refresh.

Source Options

source_options:
  # Files
  delimiter: ","
  header: true
  compression: gzip       # auto, gzip, zstd, snappy, none

  # Chunking (large tables)
  chunk_size: 1d          # 1d / 1w / 10000 (rows)
  chunk_count: 10
  range: '2024-01-01,2024-12-31'

  # JSON/API
  flatten: true
  jmespath: "data[].items"
  jq: ".results[]"

  # Type overrides
  columns:
    amount: 'decimal(18,4)'
    code: 'string'
  transforms: [trim_space]

Target Options

target_options:
  add_new_columns: true        # auto-add missing columns
  adjust_column_type: true     # widen column types as needed
  use_bulk: true               # use bulk loading (faster)
  file_max_rows: 500000        # rows per file (file targets)
  column_casing: snake         # lower / upper / snake / camel
  post_sql: "ANALYZE {table}"  # run after load
  compression: gzip            # output compression
  table_ddl: |
    CREATE TABLE {table} (id INT, name VARCHAR(255))

Hooks

hooks:
  start:
    - type: log
      message: "Starting {source.name} → {target.name}"
    - type: sql
      connection: MY_PG
      query: "UPDATE sync_log SET started_at = now() WHERE job = 'users'"
  end:
    - type: log
      message: "Completed. Rows: {stats.total_rows}"

Environment Variables

SLING_HOME_DIR     # config home (default: ~/.sling)
SLING_TEMP_DIR     # temp dir for staging files
SLING_LOGGING      # log level: info/debug/warn/error

Detailed References

Install via CLI
npx skills add https://github.com/wenerme/ai --skill sling-cli
Repository Details
star Stars 6
call_split Forks 1
navigation Branch main
article Path SKILL.md
More from Creator