What is SnowConvert CLI?

SnowConvert AI CLI (scai) encapsulates all SnowConvert functions into a single command line tool dedicated to increasing the speed of migrations from various source platforms into Snowflake.

With the SnowConvert AI CLI, migration engineers can:

  • extract code from their source platform
  • run a deterministic conversion on that code
  • deploy that code to Snowflake
  • migrate data from the source system to Snowflake
  • validate that data between the two systems

The CLI will also allow developers to create skills and agents that utilize the tool to automate their process.

Prerequisites

  • macOS, Windows, or Linux

  • SnowflakeCLI: recommended for Snowflake connection configuration SnowCLI Install Guide

  • A source database to extract from, or a set of code to use

Snowflake Connection Setup

The SnowConvert AI CLI (scai) reuses your Snowflake CLI connection configuration. The connection is used for deploy and the cloud versions of data migration and validation. Your Snowflake account also authenticates you for SnowConvert, skipping the need for an access code that was necessary in prior versions.*

Snowflake Account Requirement

Before using scai init, scai code convert, scai code extract, or scai code deploy, ensure that you:

Can connect to Snowflake with snow connection test Your Snowflake CLI has a default connection configured (this is used when you don’t specify a name).

To configure a Snowflake connection:

# Add a new connection using Snowflake CLI
snow connection add

# Set it as the default
snow connection set-default <connection_name>

# Test your connection
snow connection test

Once this is configured, commands needing a connection to Snowflake will use your Snowflake CLI connection automatically.

Installation

macOS and Linux

curl -fsSL https://snowconvert.snowflake.com/storage/linux/prod/cli/install.sh | bash

Windows

irm https://snowconvert.snowflake.com/storage/windows/prod/cli/install.ps1 | iex

Homebrew Installation (macOS only - legacy)

If you do not have homebrew installed, follow the instructions here.

There are two public channels for builds, Preview and GA.

Stable Version (recommended)

Install the stable production (GA) release:

brew tap snowflakedb/snowconvert-ai
brew install --cask snowconvert-ai

Preview Version

Install the Preview (pr) version with pre-release features from the beta/staging environment:

brew tap snowflakedb/snowconvert-ai
brew install --cask snowconvert-ai-pr

Usage

After installation, you can use the SnowConvert CLI:

scai --help

Managing Installations

View installed Version

brew info --cask snowconvert-ai
# or
brew info --cask snowconvert-ai-pr

Switch between versions

# Uninstall current version
brew uninstall --cask snowconvert-ai #or snowconvert-ai-pr

# Install another version
brew install --cask snowconvert-ai
# or
brew install --cask snowconvert-ai-pr

Update to latest version Important: you must run brew update first to sync the tap with the latest cask definitions:

# Update tap definitions and upgrade to latest version
brew update && brew upgrade --cask snowconvert-ai

# For preview version
brew update && brew upgrade --cask snowconvert-ai-pr

Why both commands? brew update synchronizes your local tap with the latest cask definitions from GitHub. Without it, brew upgrade won’t see new versions even if they exist on the server.

Installer Packages (macOS, Linux, Windows - legacy)

GA Releases

OS
Installer
macOSApple Silicon
macOSIntel
Linuxarm64 .pkg
Linuxarm64 .deb
Linuxx64 .rpm
Linuxx64 .deb
Linuxx64 .tar.gz
Linuxarm64 .tar.gz
Windowsarm64 .msi
Windowsx64 .msi

Preview Releases

OS
Installer
macOSApple Silicon
macOSIntel
Linuxarm64 .pkg
Linuxarm64 .deb
Linuxx64 .rpm
Linuxx64 .deb
Linuxx64 .tar.gz
Linuxarm64 .tar.gz
Windowsarm64 .msi
Windowsx64 .msi

Accept Terms and Conditions

Issuing the following command will display the license terms for using the SnowConvert AI CLI. It is required that you do this in order to use the product.

# display the scai terms and conditions
scai terms 

#displays terms and allows you to accept them
scai terms accept 

Understanding Projects

A project is required before you can use any other scai command. This is similar to how Git requires you to run git init before using other Git commands.

A project:

  • Organizes your migration work in a dedicated folder structure
  • Tracks your source dialect (Oracle, SQL Server, Teradata, etc.)
  • Stores configuration, source code, converted code, and reports

When you run scai init, it creates this folder structure in the target directory.

  • If you pass a PATH, scai will create that folder (if it doesn’t exist) and initialize the project inside it.
  • If you omit PATH, scai initializes the current directory (which must be empty).

The following folder structure:

project/
├── .git/
├── .gitignore
├── .scai/
│   ├── config/
│   │   ├── project.yml                        ← Team-shared config (Git)
│   │   ├── project.local.yml                  ← Personal config (gitignored)
│   │   └── conversion-context/
│   │       └── MigrationContext.json
│   └── registry/
│       ├── {uuid1}.json
│       ├── {uuid2}.json
│       ├── {uuid3}.json
│       └── .locks/                            ← SCRIPT STATE (Git)
│           └── registry.lock
├── settings/                ← User-managed settings (not created by default)
│   ├── extraction.yml
│   └── deployment.yml
├── source/                                    ← Source code Database objects
│   └── db1/
│       └── retail/                            -- schema1
│           ├── Tables/
│           │   ├── table_customers.sql
│           │   └── table_orders.sql
│           └── Stored Procedures/
│               └── proc_calculate.sql
├── snowflake/                                ← Working directory of converted code (may have manual edits, should not get overwritten)
│   ├── db1/
│   │   └── retail/                            -- schema1
│   │       ├── Tables/
│   │       │   ├── table_customers.sql
│   │       │   └── table_orders.sql
│   │       └── Stored Procedures/
│   │           └── proc_calculate.sql
│   └── dbt/                                   ← Converted scripts (optional)
│       └── models/
│           └── staging/
│               └── stg_customer_daily.sql
├── artifacts/                                 ← All artifacts related to objects
│   ├── source_raw/                            ← Original source code without changes
│   ├── db1/
│   │   ├── retail/                            -- schema1
│   │   │   └── table/             -- one folder per object kind
│   │   │       └── products/
│   │   │           ├── deterministic/         -- different runs from deterministic engine
│   │   │           │   ├── 20261201.350956/
│   │   │           │   │   └── proc_calculate.sql
│   ├── UDF Helpers/
│   └── ETL/
│   │     ├── DWH_EXAMPLE
│   │     │     ├── DWH_EXAMPLE.sql
├── reports/                                   ← Generated reports (optional in Git)
│   ├── SnowConvert/
│   │   ├── ObjectReferences.<timestamp>.csv
│   │   ├── TopLevelCodeUnits.csv
│   │   └── Issues.csv
│   ├── GenericScanner/
│   │   └── GenericScannerOutput/
│   │       ├── line_counts.pam
│   │       ├── files.pam
│   │       ├── FilesInventory.csv
│   │       ├── word_counts.pam
│   │       ├── KeywordCounts.csv
│   │       └── tool_execution.pam
│   └── ...
├── logs/
│   ├── GenericInfrastructureController/
│   ├── GenericScanner/
│   └── Snowconvert/
└── results/
    └── DataValidation/

Important: after creating a project, run all subsequent scai commands from within the project folder (where the .scai directory is).

CLI Logs are written to ~/.scai/logs/jobs.log by default

Quick Start: Code Conversion Only

Use this workflow when you have existing SQL files to convert. Works with all supported dialects.

[!IMPORTANT] You must already be in an empty directory to create a project.

#1. Create a project folder and initialize it (project name is inferred from folder name)

scai init my-project -l Oracle
cd my-project

#2. Add your source code

scai code add -i /path/to/your/sql/files

#3. Convert to Snowflake SQL

scai code convert

#4. Deploy to Snowflake

scai code deploy

Your converted code will be in the snowflake/ folder, and conversion reports in reports/.

Quick Start: End-to-End Migration

Use this workflow to extract code directly from your source database. Available for source platforms that support extraction (see Supported Source Dialects below).

Step 1: Create Project # Create a project folder and initialize it (project name is inferred from folder name)

scai init my-project -l SqlServer # or Redshift
cd my-project

Step 2: Configure Source Connection

#SQL Server (interactive mode - recommended)
scai connection add-sql-server
#Redshift (interactive mode - recommended)
scai connection add-redshift

The interactive mode will prompt you for connection details.

Set a default source connection (used with scai code extract runs without -source-connection)

scai connection set-default -l sqlserver -s <NAME>

Or

scai connection set-default -l redshift -s <NAME>

Step 3: Extract, Convert, Deploy

#extract code from source database

scai code extract

#convert to Snowflake SQL

scai code convert

#deploy to Snowflake

scai code deploy

Filtering Objects with the --where Clause

Many scai commands operate on the Code Unit Registry – a local index of every code unit (table, view, procedure, function, etc.) in your project. The --where flag lets you filter which objects a command acts on, using a SQL-like expression against that registry.

This section covers how the WHERE clause works, which commands support it, and how to use it effectively.

How the Code Unit Registry works

  1. When you run scai code add or scai code extract, source code is added to your project and split into individual code units.
  2. When you run scai code convert, the CLI builds a registry entry for every code unit, tracking its source/target metadata, object type, and conversion status.
  3. When you pass --where to a supported command, the CLI queries that registry and applies the operation only to matching objects.

The registry must exist before --where can be used. If you haven’t run at least scai code add (or scai code extract) yet, --where will fail with a “registry not found” error.

Discovering queryable fields: scai code where

Run scai code where to see the full, up-to-date reference of all queryable fields, supported operators, and usage examples. The output is generated from the actual registry library, so it is always current.

scai code where

The most commonly used fields (all field names are camelCase, all enum values are lowercase):

FieldDescriptionExample values
source.nameObject name in the source database'my_procedure'
source.objectTypeObject type in source'table', 'procedure', 'view', 'function'
source.databaseSource database name'my_db'
source.schemaSource schema name'dbo', 'public'
target.nameObject name in Snowflake'MY_PROCEDURE'
target.objectTypeObject type in Snowflake'table', 'procedure', 'view', 'function'
target.databaseTarget database name'MY_DB'
target.schemaTarget schema name'PUBLIC'
codeStatus.conversion.statusConversion result'pending', 'completed', 'failed', 'excluded'
codeStatus.registration.statusRegistration/extraction result'pending', 'completed', 'failed', 'excluded'

Previewing results: scai code find

Before running a destructive or long-running operation, use scai code find to test your filter and see which objects match:

# Show all code units in the registry
scai code find

# Test a WHERE filter
scai code find --where "target.objectType = 'table'"

# Show all results (default caps at 100)
scai code find --where "source.schema = 'dbo'" --no-limit

scai code find accepts the same --where syntax as all other commands that support it. Use it as a dry-run before committing to an operation.

Commands that support --where

The following table summarizes every scai command that accepts the --where flag:

CommandPurpose--where notes
scai code findPreview/query code units in the registryPrimary tool for testing filters before using them elsewhere
scai code convertConvert source code to Snowflake SQLOnly matched units are transformed; dependencies are still parsed for symbol resolution
scai code deployDeploy converted code to SnowflakeAlso supports --include-dependencies to automatically include objects that filtered objects depend on
scai code acceptAccept latest artifact versions into the snowflake folder
scai data migrate generate-configFilter tables written into a data migration configSelects tables from the Code Unit Registry
scai data validate generate-configFilter tables written into a data validation configSelects tables from the Code Unit Registry

Each of these commands uses the same WHERE clause syntax. The recommended workflow is:

scai code where          (learn the fields)
        ↓
scai code find --where   (preview what matches)
        ↓
scai <command> --where   (run the operation)

scai code find --where

Query the Code Unit Registry and display matching objects. This is the safest way to test a filter before using it with a command that makes changes.

scai code find --where <WHERE_CLAUSE> [--no-limit]
FlagDescription
--where <WHERE_CLAUSE>SQL-like WHERE clause to filter objects
--no-limitShow all results (default limit is 100)

Examples:

# Find all code units (no filter)
scai code find

# Find a specific object by name
scai code find --where "source.name = 'my_table'"

# Find all procedures in a schema
scai code find --where "source.schema = 'dbo' AND source.objectType = 'procedure'"

# Find objects that failed conversion
scai code find --where "codeStatus.conversion.status = 'failed'"

scai code convert --where

Convert only a filtered subset of code units to Snowflake SQL. Objects that don’t match the filter are still parsed for dependency and symbol resolution, but only matched units produce converted output.

scai code convert --where <WHERE_CLAUSE> [OPTIONS]
FlagDescription
--where <WHERE_CLAUSE>SQL-like filter to select which code units to convert
--overwrite-working-directoryOverwrite existing output files in the snowflake/ directory
-x, --show-ewisShow detailed EWI table instead of summary

Examples:

# Convert only procedures
scai code convert --where "source.objectType = 'procedure'"

# Convert objects in a single schema
scai code convert --where "source.schema = 'dbo'"

# Convert only tables and views
scai code convert --where "source.objectType IN ('table', 'view')"

Note: Even when filtering, the converter still parses all source files for symbol resolution. This ensures that cross-object references (e.g., a procedure referencing a table) are resolved correctly, even if the referenced object is not in the --where filter.


scai code deploy --where

Deploy a filtered subset of converted objects to Snowflake, instead of deploying everything.

scai code deploy --where <WHERE_CLAUSE> [--include-dependencies] [OPTIONS]
FlagDescription
--where <WHERE_CLAUSE>SQL-like WHERE clause to filter objects to deploy
--include-dependenciesAlso deploy the dependencies of the filtered code units. Has no effect without --where, since all code units are already included.
-c, --connection <CONNECTION>Snowflake connection to use
-d, --databaseTarget database name for deployment
-a, --allDeploy all successfully converted objects without selection prompt
-r, --retryNumber of retry attempts for failed deployments (default: 1)
--continue-on-errorContinue deploying remaining objects even if some fail (default: True)
--warehouse <WAREHOUSE>Warehouse override (in-memory only, applied if connection has none)
--schema <SCHEMA>Schema override (in-memory only)
--role <ROLE>Role override (in-memory only)

Examples:

# Deploy only tables
scai code deploy --where "target.objectType = 'table'"

# Deploy procedures and their dependencies (e.g. tables they reference)
scai code deploy --where "target.objectType = 'procedure'" --include-dependencies

# Deploy objects from a single schema
scai code deploy --where "source.schema = 'sales'"

# Deploy a specific object by name
scai code deploy --where "source.name = 'calculate_totals'"

Why --include-dependencies matters: When you filter with --where, you may select procedures that depend on tables or views. Without --include-dependencies, those dependent objects won’t be deployed, and the procedures may fail at runtime. Use this flag to automatically pull in everything the filtered objects need.


scai code accept --where

Accept the latest artifact versions into the snowflake output folder for a filtered subset of objects. Without --where, all objects are accepted.

scai code accept --where <WHERE_CLAUSE>
FlagDescription
--where <WHERE_CLAUSE>Filter expression to select which objects to accept

Examples:

# Accept only tables
scai code accept --where "source.objectType = 'table'"

# Accept objects from a specific schema
scai code accept --where "source.schema = 'dbo'"

# Accept only successfully converted objects
scai code accept --where "codeStatus.conversion.status = 'completed'"

scai data migrate generate-config --where / scai data validate generate-config --where

For data migration and validation, --where is applied when you generate the workflow config — it selects which tables from the Code Unit Registry are written into the YAML that scai data migrate / scai data validate then run.

scai data migrate generate-config --where <WHERE_CLAUSE> [-o <OUTPUT_PATH>] [--affinity <AFFINITY>]
scai data validate generate-config --where <WHERE_CLAUSE> [-o <OUTPUT_PATH>]
FlagDescription
--where <WHERE>SQL-like WHERE clause to filter tables from the Code Unit Registry
-o, --output <PATH>Output path for the generated YAML config (defaults under .scai/config/)
--affinity <AFFINITY>(migrate only) Affinity group for the workflow

Examples:

# Migration config for tables in the 'public' schema
scai data migrate generate-config --where "source.schema = 'public'"

# Validation config for a single table
scai data validate generate-config --where "source.name = 'customers'"

# Custom output path
scai data migrate generate-config --where "source.database = 'retail_db'" -o my-config.yaml

Note: --where filters tables at config-generation time. For code-conversion-only projects (no registry), build the table list with scai object-selector create instead.


Common --where scenarios

Inspect objects that failed conversion

After running scai code convert, some objects might have failed. Find just those to review:

# See which objects failed conversion
scai code find --where "codeStatus.conversion.status = 'failed'"

# Re-convert only that subset after fixing the source
scai code convert --where "codeStatus.conversion.status = 'failed'"

Focus on a specific object type in a specific schema

# Preview: all procedures in the dbo schema
scai code find --where "source.schema = 'dbo' AND source.objectType = 'procedure'"

# Deploy just those
scai code deploy --where "source.schema = 'dbo' AND source.objectType = 'procedure'"

Deploy only tables, then only procedures with dependencies

# Deploy tables first
scai code deploy --where "target.objectType = 'table'"

# Then deploy procedures, pulling in any remaining dependencies
scai code deploy --where "target.objectType = 'procedure'" --include-dependencies

Incremental deployment of a single schema

# Deploy everything in the 'sales' schema
scai code deploy --where "source.schema = 'sales'"

Things to keep in mind

  • Filtering data-migration tables: use scai data migrate generate-config --where (registry-backed, full-migration projects) or scai object-selector create (code-conversion-only projects).
  • The registry must exist. You need to have run at least scai code add or scai code extract before --where will work. Otherwise you’ll get a “registry not found” error.
  • Use scai code find to preview. Always test your filter with scai code find --where "..." before running a deployment job.
  • scai code where is the definitive reference. The field list in this document covers the most common fields. Run scai code where for the full, always-up-to-date list of fields, operators, and examples.

Workflow Examples

Example 1: Migrate Oracle Stored Procedures

# Create project
scai init oracle-migration -l Oracle
cd oracle-migration

# Add your PL/SQL files
scai code add -i ./oracle-procs/

# Convert
scai code convert

# Review converted code in converted/ folder, then deploy
scai code deploy --all

Example 2: SQL Server End-to-End with Specific Schema

# Create project
scai init sqlserver-migration -l SqlServer
cd sqlserver-migration

# Add connection
scai connection add-sql-server

# Extract only the 'sales' schema
scai code extract --schema sales

# Convert
scai code convert

# Deploy
scai code deploy

Example 3: Selective Migration Using --where

# Create project and convert
scai init selective-demo -l SqlServer
cd selective-demo
scai connection add-sql-server
scai code extract
scai code convert

# Preview what failed conversion
scai code find --where "codeStatus.conversion.status = 'failed'"

# Deploy only tables first
scai code deploy --where "target.objectType = 'table'"

# Deploy procedures with their dependencies
scai code deploy --where "target.objectType = 'procedure'" --include-dependencies

Getting Help

Use –help with any command to see available options:

scai --help
scai init --help
scai code convert --help
scai code where
scai connection add-redshift --help

Troubleshooting

“Project file not found” You must run commands from within a project directory. Navigate to your project folder (where the .scai/ directory exists) before running commands:

cd <project-folder>
scai code convert

“Connection not found” (source database)

  1. List your connections: scai connection list -l &lt;language&gt;
  2. Add a connection if needed: scai connection add-sql-server or scai connection add-redshift
  3. Or set a default: scai connection set-default -l &lt;language&gt; -s &lt;name&gt;

“Authentication failed” for Snowflake

The SCAI CLI uses your Snowflake CLI configuration. Ensure your connection is working:

Make sure you have a default Snowflake connection configured in the Snowflake CLI (used when no connection name is specified).

# List available Snowflake connections
snow connection list

# Test your connection
snow connection test

# Add a new connection if needed
snow connection add

“Registry not found” when using --where

The --where flag requires a Code Unit Registry, which is created when you run scai code add or scai code extract. Make sure you’ve run one of those commands before using --where:

# For file-based projects
scai code add -i /path/to/source

# For SQL Server / Redshift extraction
scai code extract

Supported Source Dialects

DialectExtractConvertDeploy
SQL ServerXXX
RedshiftXXX
TeradataXXX
OracleXXX
PostgreSQLXXX
BigQueryXXX
Azure SynapseXXX
DatabricksX
GreenplumX
SybaseX
NetezzaX
SparkX
VerticaX
HiveX
DB2X

Extract = scai code extract (live DDL extraction from a source connection). Convert = scai code convert (deterministic conversion to Snowflake SQL). Deploy = scai code deploy (deploy converted DDL into Snowflake). Redshift, SQL Server, and Teradata additionally support deploying back to the source platform with scai code deploy -t source.

Complete CLI Reference

For quick reference, here is every top-level command and subcommand available in the scai CLI:

CommandSubcommandsDescription
scai initCreate a new migration project
scai projectinfo, status, doctor, defaults set, defaults unsetView and manage project configuration
scai connectionadd-sql-server, add-redshift, add-teradata, add-oracle, add-postgresql, add-azuresynapse, add-bigquery, set-default, list, test, removeManage source database connections
scai codeextract, convert, add, deploy, find, accept, where, sync, resyncManage code migration operations
scai datamigrate, validate, worker, orchestrator, doctorData migration and validation
scai assessmentobject-exclusion, wavesGenerate migration planning insights from source code and SnowConvert reports
scai testseed, capture, validate, etl-validate, doctorGenerate and run test cases for stored procedures
scai object-selectorcreateGenerate selector files for filtering objects
scai queryExecute SQL queries on source database systems
scai settingslist, get, set, unsetView and manage user-level CLI settings
scai versionsremoveList and remove locally installed CLI versions
scai licenseinstallInstall offline license for air-gapped environments
scai termsacceptView and accept terms and conditions
scai logsShow log directory and recent log files
scai updateForce an immediate self-update on the current channel