SnowflakeのDBマイグレーションツールであるschemachangeを使ってみた

SnowflakeのDBマイグレーションツールであるschemachangeを使ってみた

2026.02.06

データ事業本部のueharaです。

今回は、SnowflakeのDBマイグレーションツールであるschemachangeを使ってみたいと思います。

schemachangeとは

schemachange は、 Snowflakeのコミュニティ開発ツールとして提供されているPythonベースのDBマイグレーションツールです。

同じくDBのマイグレーションツールとして有名な Flyway の仕組みをベースに考えられており、既にFlywayを利用したことがある方であれば取っ付きやすいツールかと思います。

バージョン管理をする変更スクリプト(SQLファイル)の命名規則は、Flywayで使用される命名規則に従う形になっています。

20260206_sc_01
参考

  • Prefix: バージョン変更を表す文字である「V」
  • Version: ドットまたはアンダースコアで任意の数の数字部分を区切った一意のバージョン番号
  • Separator: __ (アンダースコア2つ)
  • Description: アンダースコアまたはスペースで区切られた単語による任意の説明(2つのアンダースコアを含めることはできない)
  • Suffix: .sql または .sql.jinja (大文字と小文字は区別されない)

またschemachangeでは、バージョン管理を行うスクリプト( V )だけではなく、繰り返し可能なスクリプト( R )と常に実行されるスクリプト( A )にも対応しています。

Prefix 名称 挙動 スクリプトの例
V Versioned 1回のみ実行 V1.0.0__create_users_table.sql
R Repeatable チェックサム変更時に再実行 R__create_user_view.sql
A Always 毎回実行 A__grant_permissions.sql

一方で、実行可能なコマンドとしてFlywayと比較しschemachangeはより簡易的なものとなっています。

機能 Flyway Schemachange
マイグレーション実行 migrate deploy
状態確認 info なし
検証 validate verify(接続確認のみ)
テンプレート確認 なし render
修復 repair なし
全削除 clean なし
ベースライン baseline なし

schemachangeは、(少なくとも記事執筆時点では)よりシンプルさを重視した設計であるように見えます。

やってみた

事前準備

Snowflake上で、事前に UEHARA_TEST_DBMETADATA という名前のDBを作成しておきます。

USE ROLE SYSADMIN;

CREATE DATABASE UEHARA_TEST_DB;
CREATE DATABASE METADATA;

20260206_sc_00

後段の処理ではこれらのDBを使うことにします。

schemachangeのインストール

まず、schemachangeのインストールを行います。

冒頭で述べた通りPythonベースのツールとなっているので、以下コマンドでインストールできます。

pip install schemachange

初回のファイル作成

手始めに、以下のようなディレクトリ構成を作成します。

.
├── migrations
│   ├── V1.0.0__create_test_schema.sql
│   └── V1.1.0__create_items_table.sql
└── schemachange-config.yml

schemachange-config.yml はschemachangeの設定ファイルになります。

記載方法についてはドキュメントに記載の通りですが、今回は以下のようにしてみました。

schemachange-config.yml
config-version: 2

schemachange:
  # The root folder for the database change scripts
  root-folder: './migrations'

  # Used to override the default name of the change history table (default: METADATA.SCHEMACHANGE.CHANGE_HISTORY)
  change-history-table: 'METADATA.SCHEMACHANGE.CHANGE_HISTORY'

  # Define values for variables to be replaced in change scripts
  vars:
    environment: 'dev'

  # Create the change history schema and table if they do not exist (default: false)
  create-change-history-table: true

  # Log level: DEBUG, INFO, WARNING, ERROR, or CRITICAL (default: INFO)
  log-level: 'INFO'

  # Regex pattern for version number validation
  version-number-validation-regex: '^[0-9]+\.[0-9]+\.[0-9]+$'

最初に作る変更スクリプトは以下のようにしてみました。

V1.0.0__create_test_schema.sql
CREATE SCHEMA TEST_SCHEMA;
V1.1.0__create_items_table.sql
CREATE TABLE TEST_SCHEMA.ITEMS (
    id INTEGER PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    price INTEGER NOT NULL
);

接続設定と疎通確認

Snowflakeの接続情報として、環境変数に値を設定します。

export SNOWFLAKE_ACCOUNT="<YOUR_ACCOUNT>"
export SNOWFLAKE_USER="<YOUR_USER>"
export SNOWFLAKE_PRIVATE_KEY_PATH="<YOUR_KEY_PATH>"
export SNOWFLAKE_PRIVATE_KEY_PASSPHRASE="<YOUR_KEY_PASSPHRASE>"
export SNOWFLAKE_ROLE="<YOUR_ROLE>"
export SNOWFLAKE_WAREHOUSE="<YOUR_WAREHOUSE>"
export SNOWFLAKE_DATABASE="<YOUR_DB>"

設定ができたら、以下コマンドで疎通確認を行います。

schemachange verify

出力の最後に以下のように表示されれば接続ができています。

20260206_sc_02

デプロイ(1回目)

接続の確認ができたので、デプロイしてみます。

schemachange deploy

出力の最後に以下のように表示されていればデプロイ成功です。

スクリーンショット 2026-02-06 11.56.26

実際にSnowlake上にデータを見に行くと、変更履歴の管理用テーブルとSQLで指定したスキーマ及びテーブルが作成されていることが分かります。

20260206_sc_03

変更履歴のテーブルを確認すると、以下のように実行ステータスの確認ができます。

20260206_sc_04

ファイルの追加

次に、以下の通りファイルの追加をしてみます。

.
├── migrations
│   ├── R__items_view.sql   ★新規作成
│   ├── V1.0.0__create_test_schema.sql
│   ├── V1.1.0__create_items_table.sql
│   └── V1.1.1__alter_items_add_column.sql   ★新規作成
└── schemachange-config.yml

追加した2ファイルは以下の通りです。

R__items_view.sql
CREATE OR REPLACE VIEW TEST_SCHEMA.ITEMS_VIEW AS
SELECT
    id,
    name,
    price,
    description
FROM TEST_SCHEMA.ITEMS;
V1.1.1__alter_items_add_column.sql
ALTER TABLE TEST_SCHEMA.ITEMS ADD COLUMN description VARCHAR(1024);

デプロイ(2回目)

ファイルの追加が完了したので、再度デプロイを行います。

schemachange deploy

結果は次の通りで、バージョン指定したものについては履歴からMaxのバージョンを確認し、以降のスクリプトが実行されていることが分かります。

R で指定したビューは現状未作成のものなので、このタイミングで新規作成されています。

20260206_sc_05

Snoflake上でもビューの作成とテーブルへのカラムの追加が確認できました。

20260206_sc_07

20260206_sc_08

このタイミングでもう1度デプロイを実行してみます。

schemachange deploy

結果は次の通りで、反映すべきスクリプトが無いので何も適用していないことが分かります。

20260206_sc_06

異常系の動作確認

正常系は何となく挙動が見れたので、今度はあえて誤った操作をしてみます。

バージョンを誤ったファイルの追加

既に適用済みのバージョンより過去のバージョンのファイルを追加してみます。

.
├── migrations
│   ├── R__items_view.sql
│   ├── V1.0.0__create_test_schema.sql
│   ├── V1.0.1__create_sample_schema.sql   ★新規作成
│   ├── V1.1.0__create_items_table.sql
│   └── V1.1.1__alter_items_add_column.sql
└── schemachange-config.yml

この状態でデプロイを実行すると、エラーメッセージは特に出ませんが、ファイルがSkipされるため、シンプルに適用がされません。

schemachange deploy

20260206_sc_09

環境反映済みのバージョン管理スクリプトの修正

今度は、既に環境反映済みのバージョン管理スクリプトを修正してみます。

V1.1.1__alter_items_add_column.sql
ALTER TABLE TEST_SCHEMA.ITEMS ADD COLUMN description VARCHAR(1024);
+ALTER TABLE TEST_SCHEMA.ITEMS ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP();

先程の挙動から明らかにはなりますが、この状態でデプロイしてもバージョン的に処理はスキップされるため、反映はされません。

schemachange deploy

20260206_sc_10

ここが少し事故が起こりそうだなと思う部分ですが、過去のバージョンの作成や、適用済みのファイルに変更を加えたとしてもデプロイコマンドでは特にエラーにはなりません。

Flywayであればこのようなケースではデプロイ(migrate)時にエラーとなりますが、schemachangeはそのようになっていないようなので注意が必要です。

補足:Jinjaテンプレートの活用

schemachangeではJinjaテンプレートをサポートしているため、動的なSQLスクリプトが作成可能です。

例えば先の schemachange-config.yml では、変数として以下を設定していました。

  vars:
    environment: 'dev'

これを利用し、例えば以下のようなスクリプトファイルの記述が可能です。

V1.2.0__create_users_table.sql
CREATE TABLE TEST_SCHEMA.{{environment}}_USERS (
    id INTEGER PRIMARY KEY,
    name VARCHAR(255) NOT NULL
);

render コマンドを利用することで、どのようなSQLファイルが実行されるか確認することもできます。

schemachange render migrations/V1.2.0__create_users_table.sql

20260206_sc_11

ちなみに変数はデプロイ時に --vars オプションで変更可能なので、例えば環境毎に変数を上書きすることもできます。

schemachange render --vars '{"environment": "prod"}' migrations/V1.2.0__create_users_table.sql

20260206_sc_12

最後に

今回は、SnowflakeのDBマイグレーションツールであるschemachangeを使ってみました。

参考になりましたら幸いです。

参考文献

この記事をシェアする

FacebookHatena blogX

関連記事