RepoSnowflake (Arctic)Snowflake (Arctic)published Aug 27, 2018seen 5d

Snowflake-Labs/schemachange

Python

Open original ↗

Captured source

source ↗
published Aug 27, 2018seen 5dcaptured 8hhttp 200method plain

Snowflake-Labs/schemachange

Description: A Database Change Management tool for Snowflake

Language: Python

License: Apache-2.0

Stars: 663

Forks: 290

Open issues: 42

Created: 2018-08-27T06:24:28Z

Pushed: 2026-05-11T18:32:51Z

Default branch: master

Fork: no

Archived: no

README:

schemachange

*Looking for snowchange? You've found the right spot. snowchange has been renamed to schemachange.*

![pytest](https://github.com/Snowflake-Labs/schemachange/actions/workflows/master-pytest.yml)

Overview

schemachange is a simple python based tool to manage all of your Snowflake objects. It follows an Imperative-style approach to Database Change Management (DCM) and was inspired by the Flyway database migration tool. When combined with a version control system and a CI/CD tool, database changes can be approved and deployed through a pipeline using modern software delivery practices. As such schemachange plays a critical role in enabling Database (or Data) DevOps.

DCM tools (also known as Database Migration, Schema Change Management, or Schema Migration tools) follow one of two approaches: Declarative or Imperative. For a background on Database DevOps, including a discussion on the differences between the Declarative and Imperative approaches, please read the Embracing Agile Software Delivery and DevOps with Snowflake blog post.

For the complete list of changes made to schemachange check out the [CHANGELOG](CHANGELOG.md).

To learn more about making a contribution to schemachange, please see our [Contributing guide](.github/CONTRIBUTING.md).

For maintainers: See [docs/maintainers](docs/maintainers/) for repository management guides.

Please note that schemachange is a community-developed tool, not an official Snowflake offering. It comes with no support or warranty.

Quick Start

Get schemachange running in 5 minutes:

1. Install schemachange

pip install schemachange

2. Create your first migration script

mkdir -p migrations
cat > migrations/V1.0.0__initial_setup.sql

With the following rules for each part of the filename:

* **Prefix**: The letter 'V' for versioned change
* **Version**: A unique version number with dots or underscores separating as many number parts as you like
* **Separator**: __ (two underscores)
* **Description**: An arbitrary description with words separated by underscores or spaces (can not include two
underscores)
* **Suffix**: .sql or .sql.jinja (case-insensitive: .SQL, .Sql, .JINJA also work)

For example, a script name that follows this convention is: `V1.1.1__first_change.sql`. As with Flyway, the unique
version string is very flexible. You just need to be consistent and always use the same convention, like 3 sets of
numbers separated by periods. Here are a few valid version strings:

* 1.1
* 1_1
* 1.2.3
* 1_2_3

Every script within a database folder must have a unique version number. schemachange will check for duplicate version
numbers and throw an error if it finds any. This helps to ensure that developers who are working in parallel don't
accidentally (re-)use the same version number.

### Repeatable Script Naming

Repeatable change scripts follow a similar naming convention to that used
by [Flyway Versioned Migrations](https://documentation.red-gate.com/fd/repeatable-migrations-273973335.html). The
script name must follow this pattern (image taken
from [Flyway docs](https://documentation.red-gate.com/fd/repeatable-migrations-273973335.html):


e.g:

* R__sp_add_sales.sql
* R__fn_get_timezone.sql
* R__fn_sort_ascii.sql

All repeatable change scripts are applied each time the utility is run, if there is a change in the file.
Repeatable scripts could be used for maintaining code that always needs to be applied in its entirety. e.g. stored
procedures, functions and view definitions etc.

Just like Flyway, within a single migration run, repeatable scripts are always applied after all pending versioned
scripts have been executed. Repeatable scripts are applied in alphabetical order of their description.

### Always Script Naming

Always change scripts are executed with every run of schemachange. This is an addition to the implementation
of [Flyway Versioned Migrations](https://documentation.red-gate.com/fd/versioned-migrations-273973333.html).
The script name must follow this pattern:

`A__Some_description.sql`

e.g.

* A__add_user.sql
* A__assign_roles.sql

This type of change script is useful for an environment set up after cloning. Always scripts are applied always last.

### CLI Migration Scripts

CLI migration scripts allow you to execute command-line tools as part of your deployment process. This is useful for deploying complex objects in Snowflake that go beyond SQL (such as a dbt Project or Snowpark object) and would require the use of the Snowflake CLI.

CLI migration scripts use a YAML format with the `.cli.yml` extension (or `.cli.yml.jinja` for Jinja templating). They follow the same naming conventions as SQL scripts:

* `V1.0.0__deploy_dbt_project.cli.yml` - Versioned CLI script
* `R__refresh_snowpark_function.cli.yml` - Repeatable CLI script
* `A__cleanup.cli.yml` - Always CLI script

#### YAML Schema

CLI migration scripts define a list of steps to execute:

steps:

  • cli: snow

command: dbt args:

  • "deploy"
  • "--connection"
  • "myconnection"

working_dir: ./my_dbt_project description: "Deploy the Snowflake dbt Project"

  • cli: snow

command: snowpark args:

  • "deploy"
  • "--connection"
  • "myconnection"

working_dir: ./my_snowpark_function description: "Deploy the Snowpark function"

#### Step Fields

| Field | Required | Description |
|-------|----------|-------------|
| `cli` | Yes | CLI tool to execute. Currently only `snow` (Snowflake CLI) is supported. |
| `command` | Yes | The command to run (e.g., `app`, `sql`, `connection`). |
| `args` | No | List of arguments to pass to the command. Each argument must be a separate list item. |
| `working_dir` | No | Working directory for command execution. Resolved relative to root-folder. Defaults to root-folder. |
| `env` | No | Environment variables to set for the command (key-value pairs). |
| `description` | No | Human-readable description of what this step does. |…

Excerpt shown — open the source for the full document.