PowerShellでSnowflakeのStageを作成し大量データを簡単にロードする方法

PowerShellを活用してSnowflakeのStageを作成し、大量データを効率的にロードする方法は、データ処理や管理のプロセスを大幅に簡略化する強力なアプローチです。Snowflakeは、クラウドベースのデータウェアハウスソリューションとして、多量のデータを効率的に管理する機能を提供します。一方、PowerShellは自動化やスクリプト作成を得意とするツールであり、これらを組み合わせることで、日常的なデータロード作業をより迅速かつ効率的に行うことができます。本記事では、PowerShellを用いてSnowflakeのStageを作成し、効率的なデータロードを実現する具体的な方法やステップを詳しく解説します。これにより、業務プロセスの合理化とデータ管理の最適化を目指しましょう。

目次

SnowflakeのStageとは


SnowflakeのStageは、外部ファイルをSnowflakeにロードするための一時的なストレージエリアを指します。Stageは、データウェアハウスにデータを取り込む際の中間ステップとして機能し、ファイルをクラウドストレージやローカルシステムからSnowflakeにロードするために利用されます。

Stageの種類


Snowflakeには以下のようなStageの種類があります:

1. ユーザーStage


各ユーザーに割り当てられるStageで、個々のユーザーが利用可能です。

2. テーブルStage


特定のテーブルに関連付けられたStageで、そのテーブルへのデータロードに利用されます。

3. 内部Stage


Snowflakeアカウント内にホストされる内部ストレージを利用したStageです。

4. 外部Stage


Amazon S3、Google Cloud Storage、Microsoft Azure Blob Storageなどの外部クラウドストレージを利用するStageです。

Stageを利用するメリット

  • データロードの簡便化: Stageを利用することで、ファイルを直接ロードするのではなく、事前にアップロードされたデータを簡単に管理できます。
  • スケーラビリティ: 大規模データを効率的にロードするための柔軟性を提供します。
  • エラー管理の容易さ: データロードプロセスで発生する問題を特定しやすくなります。

PowerShellを利用したStageの操作


PowerShellスクリプトを使うことで、SnowflakeのStageの作成、管理、およびデータロードが効率化されます。具体的な手順は次項で解説します。

PowerShellを使用するメリット

PowerShellは、Windows環境で特に広く使用されるスクリプト言語およびコマンドラインツールであり、Snowflakeのようなクラウドベースのデータウェアハウスの操作を簡略化するのに適しています。以下に、PowerShellを使用する主なメリットを説明します。

1. 自動化の容易さ


PowerShellはスクリプトの作成が容易であり、繰り返し実行されるタスクを自動化できます。

  • データロードのスケジューリング: 定期的なデータ更新を自動化可能。
  • Stageの管理: Stage作成やファイルのアップロードなどを一括で処理。

2. 他システムとの統合


PowerShellは、APIやコマンドラインツールを介して他のシステムと容易に統合可能です。

  • Snowflake APIとの連携: REST APIを利用してSnowflakeの各種操作が可能。
  • 外部ツールとの連携: AWS S3やAzure Blob Storageなどのクラウドサービスにアクセス。

3. 柔軟なスクリプト機能


PowerShellは、変数や条件分岐、ループ処理などの高度なプログラミング機能を提供します。

  • 動的スクリプト: 動的にパラメータを設定し、複数の操作を効率化。
  • ログ管理: スクリプトの実行履歴を記録してトラブルシューティングを容易に。

4. コスト効率


PowerShellはWindowsに標準で付属しており、追加のソフトウェアやライセンスが不要です。

  • 無料ツール: 追加コストなしで利用可能。
  • 時間の節約: 手動作業をスクリプト化することで時間を大幅に節約。

5. 学習のしやすさ


PowerShellは学習曲線が緩やかで、初心者から上級者まで幅広い層に対応しています。

  • 直感的なコマンド: シンプルな構文で理解しやすい。
  • 豊富なドキュメント: マイクロソフトやコミュニティから提供される豊富なリソース。

PowerShellとSnowflakeの組み合わせ


Snowflakeのデータ操作をPowerShellで行うことで、スクリプトによる効率的なデータロードやエラー処理が可能になります。次項では、Snowflake環境の設定とPowerShellの連携方法について解説します。

Snowflake環境の前提条件

PowerShellを利用してSnowflakeを操作するには、事前にいくつかの環境設定とツールの準備が必要です。ここでは、必要な前提条件を詳しく解説します。

1. Snowflakeアカウント


Snowflakeを操作するためには、有効なSnowflakeアカウントが必要です。以下の情報を準備してください:

  • アカウント名: SnowflakeのURLで使用するアカウント名(例: xyz123.snowflakecomputing.com)。
  • ユーザー名とパスワード: 接続に使用する認証情報。

2. PowerShellのセットアップ


PowerShellが適切に動作する環境を整える必要があります。

  • PowerShellのバージョン: PowerShell 5.1以上またはPowerShell Coreを推奨。
  • モジュールのインストール: 必要なモジュールをインストールします。たとえば、Snowflake.Data(.NETライブラリ)やInvoke-RestMethod(API呼び出し用コマンド)を利用します。

3. Snowflake CLIまたはODBCドライバ


Snowflakeとの通信を行うためには、以下のいずれかをセットアップします。

SnowSQL(CLIツール)


公式のCLIツールであり、Snowflakeへの直接的なコマンド実行が可能です。

  • ダウンロードとインストール: 公式SnowflakeドキュメントからSnowSQLを入手します。
  • 認証情報の設定: SnowSQLプロファイルを作成し、接続情報を保存します。

ODBCドライバ


ODBC経由でデータベースに接続する場合は、Snowflake ODBCドライバをインストールします。

4. 必要なPowerShellスクリプトツール


PowerShellからSnowflakeにアクセスするために、以下のツールを利用できます:

  • Invoke-SnowflakeQuery: カスタムスクリプトを作成し、SQLクエリを実行。
  • Snowflake API: REST APIを利用して、Stageの作成やデータロード操作を実行。

5. ネットワーク設定


Snowflakeにアクセスする際、ファイアウォールやネットワークの設定に注意が必要です。

  • 必要なポート: HTTPS(ポート443)が許可されていること。
  • ホワイトリスト設定: 必要に応じてSnowflakeサーバーのIPアドレスをホワイトリストに登録します。

6. 環境の確認


すべてのツールと設定が適切に動作するか確認するために、以下を実行します:

  • 接続テスト: Snowflakeに接続し、基本的なSQLクエリを実行して動作確認。
  • バージョン確認: 使用しているツールやドライバが最新であることを確認。

これらの前提条件が整ったら、次にPowerShellを使ったSnowflakeへの認証設定を行います。

次の項目をご指定ください。その内容に基づき具体的な記事作成を進めます!

PowerShellによる認証の設定

PowerShellを利用してSnowflakeに接続する際、認証設定を正しく行うことが重要です。ここでは、認証情報の設定手順と、PowerShellスクリプトを使用した接続方法を解説します。

1. 認証情報の準備


Snowflakeに接続するためには、以下の情報が必要です:

  • アカウント名: SnowflakeのURL(例: xyz123.snowflakecomputing.com)。
  • ユーザー名: Snowflakeアカウントに登録されたユーザー名。
  • パスワード: ユーザーアカウントに対応するパスワード。
  • ロール: Snowflakeの操作に必要な権限を持つロール(例: SYSADMIN)。

2. PowerShellスクリプトでの接続設定


以下のスクリプトを使用して、Snowflakeに接続する認証を設定します。

# 認証情報の設定
$accountName = "xyz123.snowflakecomputing.com"
$username = "your_username"
$password = "your_password"
$role = "SYSADMIN"

# 接続文字列の作成
$connectionString = "Account=$accountName;User=$username;Password=$password;Role=$role"

# ODBC接続の作成
$connection = New-Object System.Data.Odbc.OdbcConnection
$connection.ConnectionString = $connectionString

# 接続を開く
try {
    $connection.Open()
    Write-Host "Snowflakeに接続しました。"
} catch {
    Write-Host "接続に失敗しました: $($_.Exception.Message)"
}

3. 認証プロファイルの活用


SnowSQLのプロファイルを利用する場合、設定済みのプロファイルをPowerShellで呼び出すことも可能です。これにより、認証情報をスクリプトに直接記載せず、セキュリティを強化できます。
SnowSQLのプロファイル設定例:

[connections.snowflake_profile]
accountname=xyz123
username=your_username
password=your_password

プロファイルを利用したPowerShellスクリプト

# SnowSQLプロファイルを参照する
$profile = "snowflake_profile"
$snowsqlPath = "C:\Program Files\Snowflake SnowSQL\snowsql.exe"

# SnowSQLを利用して認証
& $snowsqlPath -c $profile -q "SELECT CURRENT_USER(), CURRENT_ROLE();"

4. トークン認証の活用(オプション)


セキュリティを強化するために、トークンベース認証(例えばOAuthまたはJWT)を利用することも可能です。これにより、パスワードを直接使用せずに接続できます。

5. 接続テスト


以下のクエリを実行して、認証が正しく設定されていることを確認します。

# サンプルクエリ
$query = "SELECT CURRENT_USER(), CURRENT_ROLE();"
$command = $connection.CreateCommand()
$command.CommandText = $query

# クエリを実行
try {
    $result = $command.ExecuteReader()
    while ($result.Read()) {
        Write-Host "ユーザー: $($result.GetString(0)), ロール: $($result.GetString(1))"
    }
} catch {
    Write-Host "クエリ実行に失敗しました: $($_.Exception.Message)"
}

まとめ


PowerShellを用いたSnowflakeの認証設定は、シンプルで柔軟性があり、スクリプトを利用した効率的な操作を可能にします。この手順を踏むことで、安全かつ確実にSnowflakeと連携する基盤を整えられます。次項では、Stageの作成方法について解説します。

Stageの作成手順

SnowflakeのStageは、外部ファイルを効率的に管理し、大量データをSnowflakeにロードするための重要な役割を果たします。ここでは、PowerShellを利用してStageを作成する具体的な手順を説明します。

1. Stage作成の基本概要


Stageは、以下のような用途に応じて作成されます:

  • 内部Stage: Snowflake内部のストレージを使用する場合に利用。
  • 外部Stage: Amazon S3やGoogle Cloud Storageなどの外部ストレージを使用する場合に利用。

2. 内部Stageの作成


以下は、内部Stageを作成するPowerShellスクリプト例です。

# 内部Stage作成SQL
$createStageQuery = @"
CREATE OR REPLACE STAGE my_internal_stage
FILE_FORMAT = (TYPE = 'CSV' FIELD_OPTIONALLY_ENCLOSED_BY = '"')
"@

# SQLコマンドの実行
$command = $connection.CreateCommand()
$command.CommandText = $createStageQuery

try {
    $command.ExecuteNonQuery()
    Write-Host "内部Stage 'my_internal_stage' を作成しました。"
} catch {
    Write-Host "Stageの作成に失敗しました: $($_.Exception.Message)"
}

3. 外部Stageの作成


外部Stageを作成する際は、ストレージの認証情報を含むURLを指定します。以下はS3を使用した例です。

# 外部Stage作成SQL
$createStageQuery = @"
CREATE OR REPLACE STAGE my_external_stage
URL = 's3://my-bucket-name/'
CREDENTIALS = (AWS_KEY_ID='your_aws_key_id' AWS_SECRET_KEY='your_aws_secret_key')
FILE_FORMAT = (TYPE = 'CSV' FIELD_OPTIONALLY_ENCLOSED_BY = '"')
"@

# SQLコマンドの実行
$command = $connection.CreateCommand()
$command.CommandText = $createStageQuery

try {
    $command.ExecuteNonQuery()
    Write-Host "外部Stage 'my_external_stage' を作成しました。"
} catch {
    Write-Host "Stageの作成に失敗しました: $($_.Exception.Message)"
}

4. Stageの確認


作成されたStageを確認するには、以下のSQLを実行します。

# Stage確認SQL
$describeStageQuery = "DESCRIBE STAGE my_external_stage"

# 実行
$command.CommandText = $describeStageQuery
try {
    $reader = $command.ExecuteReader()
    while ($reader.Read()) {
        Write-Host "$($reader.GetString(0)) = $($reader.GetString(1))"
    }
} catch {
    Write-Host "Stageの確認に失敗しました: $($_.Exception.Message)"
}

5. 作成後の注意点

  • ファイル形式の設定: 必要に応じてFILE_FORMATの詳細設定を行います。
  • アクセス権の管理: 適切なユーザーやロールに権限を付与します。

まとめ


PowerShellを活用することで、内部Stageおよび外部Stageを簡単に作成・管理することが可能です。これにより、大量データのロード準備が効率化されます。次項では、Stageを利用したデータのロード方法を解説します。

大量データのロード方法

SnowflakeのStageを利用することで、大量データを効率的にロードすることが可能です。ここでは、PowerShellを使用してデータをStageにアップロードし、Snowflakeテーブルにロードする具体的な手順を解説します。

1. データロードの基本手順


データをSnowflakeにロードする流れは以下の通りです:

  1. ファイルをStageにアップロードする。
  2. SnowflakeのCOPY INTOコマンドを使用して、Stageからテーブルにデータをロードする。

2. Stageへのファイルアップロード


PowerShellを使用して外部ストレージ(例: Amazon S3)またはSnowflake内部Stageにファイルをアップロードします。

例: Snowflake内部Stageへのファイルアップロード

以下のスクリプトでは、PUTコマンドを使用してローカルファイルを内部Stageにアップロードします。

# ファイルアップロードSQL
$uploadFileQuery = @"
PUT file://C:/data/sample_data.csv @my_internal_stage
"@

# SQLコマンドの実行
$command = $connection.CreateCommand()
$command.CommandText = $uploadFileQuery

try {
    $command.ExecuteNonQuery()
    Write-Host "ファイル 'sample_data.csv' を内部Stage 'my_internal_stage' にアップロードしました。"
} catch {
    Write-Host "ファイルアップロードに失敗しました: $($_.Exception.Message)"
}

例: 外部ストレージへのファイルアップロード


外部Stageを使用する場合は、対象のクラウドストレージ(例: S3)に直接ファイルをアップロードします。ここでは、AWS CLIまたはS3用PowerShellコマンドレットを使用します。

# S3へのファイルアップロード
$bucketName = "my-bucket-name"
$filePath = "C:/data/sample_data.csv"
$awsAccessKey = "your_aws_access_key"
$awsSecretKey = "your_aws_secret_key"

# AWS Tools for PowerShellを使用
Set-AWSCredentials -AccessKey $awsAccessKey -SecretKey $awsSecretKey
Write-S3Object -BucketName $bucketName -File $filePath -Key "sample_data.csv"
Write-Host "ファイル 'sample_data.csv' をS3バケットにアップロードしました。"

3. Stageからテーブルへのデータロード


SnowflakeのCOPY INTOコマンドを使用して、StageからSnowflakeテーブルにデータをロードします。

# データロードSQL
$loadDataQuery = @"
COPY INTO my_table
FROM @my_internal_stage
FILE_FORMAT = (TYPE = 'CSV' FIELD_OPTIONALLY_ENCLOSED_BY = '"')
ON_ERROR = 'CONTINUE'
"@

# SQLコマンドの実行
$command.CommandText = $loadDataQuery

try {
    $command.ExecuteNonQuery()
    Write-Host "Stageからテーブル 'my_table' にデータをロードしました。"
} catch {
    Write-Host "データロードに失敗しました: $($_.Exception.Message)"
}

4. データロード結果の確認


データロード結果を確認するためには、以下のSQLを実行してロードされた行数やエラーの有無をチェックします。

# ロード結果確認SQL
$checkLoadQuery = "SELECT COUNT(*) FROM my_table"

$command.CommandText = $checkLoadQuery
try {
    $reader = $command.ExecuteReader()
    while ($reader.Read()) {
        Write-Host "ロードされた行数: $($reader.GetInt32(0))"
    }
} catch {
    Write-Host "結果確認に失敗しました: $($_.Exception.Message)"
}

5. エラー時の対処


ON_ERRORオプションをCONTINUEに設定している場合、エラー行をスキップして処理を続行します。エラーファイルの確認方法も次項で詳しく解説します。

まとめ


PowerShellとSnowflakeのStage機能を組み合わせることで、大量データを効率的にロードすることができます。このプロセスにより、手動操作を最小限に抑え、大規模なデータ処理を簡略化できます。次項では、データロード中のエラー処理とトラブルシューティングについて解説します。

エラー処理とトラブルシューティング

データロード中に発生する可能性のあるエラーを適切に処理し、トラブルシューティングを行うことは、スムーズな運用において重要です。ここでは、よくあるエラーの種類とそれに対する対処方法を解説します。

1. よくあるエラーの種類

ファイル形式エラー

  • 原因: Snowflakeで定義されたFILE_FORMATと、ロードするデータの形式が一致しない。
  • 例: CSVデータにヘッダー行が含まれているが、SKIP_HEADERが設定されていない。

認証エラー

  • 原因: Snowflakeの接続情報が正しくない、または外部Stageへのアクセス権が不足している。
  • 例: AWS S3バケットのキーやシークレットが間違っている。

データ型エラー

  • 原因: テーブル定義のカラム型に対して、ロードされるデータの型が一致しない。
  • 例: INT型カラムに文字列データが含まれている。

ステージングエラー

  • 原因: ファイルがStageに正しくアップロードされていない。
  • 例: PUTコマンドでファイルパスが間違っている。

2. エラー処理方法

データロード時のエラー処理


SnowflakeのCOPY INTOコマンドでは、エラー処理オプションを設定することが可能です。

  • ON_ERROR = CONTINUE: エラー行をスキップして処理を続行。
  • ON_ERROR = ABORT_STATEMENT: エラー発生時にすべての操作を中止。

例: COPY INTOコマンドのエラー処理設定

COPY INTO my_table
FROM @my_internal_stage
FILE_FORMAT = (TYPE = 'CSV')
ON_ERROR = 'CONTINUE';

エラーログの確認


エラーの詳細を確認するには、以下のクエリを使用してロード結果を調査します。

SELECT * FROM table($LOAD_HISTORY(@my_internal_stage));

3. トラブルシューティングのステップ

1. 接続エラーの確認

  • Snowflakeアカウントやユーザー名、パスワードを再確認する。
  • ネットワーク接続やファイアウォールの設定を確認する。

2. ファイル形式の確認

  • ロードするデータの形式が定義されたFILE_FORMATと一致しているか確認する。
  • 必要に応じて以下のようにFILE_FORMATを修正:
CREATE OR REPLACE FILE FORMAT my_csv_format
TYPE = 'CSV'
FIELD_OPTIONALLY_ENCLOSED_BY = '"'
SKIP_HEADER = 1;

3. データ型エラーの確認

  • エラーログを確認し、不正なデータ型が含まれている行を特定する。
  • 問題のあるデータを修正するか、エラー行をスキップする設定を追加する。

4. Stageの確認

  • Stageに正しくファイルがアップロードされているか確認する:
LIST @my_internal_stage;

4. PowerShellスクリプトでのエラーハンドリング


PowerShellスクリプトでも、エラーハンドリングを組み込むことで効率的に処理を管理できます。

try {
    # SQL実行
    $command.CommandText = $loadDataQuery
    $command.ExecuteNonQuery()
    Write-Host "データロードが成功しました。"
} catch {
    Write-Host "データロード中にエラーが発生しました: $($_.Exception.Message)"
    # エラーログを保存
    $errorLogPath = "C:/logs/error_log.txt"
    $_.Exception.Message | Out-File -FilePath $errorLogPath -Append
    Write-Host "エラーログを $errorLogPath に保存しました。"
}

5. より高度なエラー管理

  • 再試行ロジックの実装: ネットワークエラーなど一時的な問題の場合、処理を再試行するロジックを組み込む。
  • 通知機能: エラーが発生した場合、メールやSlack通知を送ることで迅速に対応可能。

まとめ


エラー処理とトラブルシューティングは、大量データロードの信頼性を向上させる鍵です。適切なエラーハンドリングとログ管理を実装することで、運用時の問題を迅速に解決できます。次項では、PowerShellを使用したデータ更新の自動化について解説します。

応用例:定期的なデータ更新の自動化

データ管理の効率をさらに向上させるため、PowerShellを使用してSnowflakeでのデータ更新作業を自動化する方法を解説します。定期的なデータロードやStageの管理をスクリプトで自動化することで、作業負担を軽減できます。

1. 定期実行の必要性


企業やプロジェクトでは、日次や週次のデータ更新が求められる場面が多くあります。以下の理由から、自動化は重要です:

  • 時間の節約: 手動操作を排除し、リソースを効率的に活用。
  • エラーの削減: スクリプトにより一貫した処理が可能。
  • スケーラビリティ: 大量データの更新作業を迅速に実行。

2. 自動化の準備

スクリプトファイルの作成


以下のPowerShellスクリプトは、データ更新タスクを実行するものです:

# スクリプトの設定
$accountName = "xyz123.snowflakecomputing.com"
$username = "your_username"
$password = "your_password"
$role = "SYSADMIN"

# 接続文字列の作成
$connectionString = "Account=$accountName;User=$username;Password=$password;Role=$role"

# ODBC接続
$connection = New-Object System.Data.Odbc.OdbcConnection
$connection.ConnectionString = $connectionString

try {
    $connection.Open()
    Write-Host "Snowflakeに接続しました。"

    # データ更新クエリ
    $loadQuery = @"
    COPY INTO my_table
    FROM @my_internal_stage
    FILE_FORMAT = (TYPE = 'CSV')
    ON_ERROR = 'CONTINUE';
    "@

    # クエリ実行
    $command = $connection.CreateCommand()
    $command.CommandText = $loadQuery
    $command.ExecuteNonQuery()
    Write-Host "データを更新しました。"
} catch {
    Write-Host "エラーが発生しました: $($_.Exception.Message)"
} finally {
    $connection.Close()
    Write-Host "接続を閉じました。"
}

3. 定期実行の設定

Windowsタスクスケジューラを使用

  1. タスクの作成:
  • Windowsタスクスケジューラを開き、「基本タスクの作成」を選択。
  • 名前と説明を入力。
  1. トリガーの設定:
  • 実行頻度(例: 毎日、毎週)を設定。
  • 実行時間を指定。
  1. アクションの設定:
  • 「プログラムの開始」を選択。
  • powershell.exe を指定し、作成したスクリプトのパスを引数として入力。
    例:
   powershell.exe -File "C:\scripts\update_snowflake_data.ps1"

PowerShellスクリプト内でのログ管理


自動化処理の結果をログとして記録することで、後からトラブルシューティングが容易になります。

# ログファイルのパス
$logPath = "C:\logs\data_update_log.txt"

# ログ記録
try {
    $logEntry = "$(Get-Date): データ更新開始"
    $logEntry | Out-File -FilePath $logPath -Append

    # 実行する処理(スクリプト内容)
    $logEntry = "$(Get-Date): データ更新成功"
    $logEntry | Out-File -FilePath $logPath -Append
} catch {
    $logEntry = "$(Get-Date): エラー - $($_.Exception.Message)"
    $logEntry | Out-File -FilePath $logPath -Append
}

4. メール通知機能の追加(オプション)


処理の成功や失敗を通知するメールを自動送信することも可能です。

# メール通知設定
Send-MailMessage -From "[email protected]" `
                 -To "[email protected]" `
                 -Subject "データ更新結果通知" `
                 -Body "データ更新が完了しました。" `
                 -SmtpServer "smtp.example.com"

5. 効率的な運用のためのベストプラクティス

  • 環境分離: 本番環境とテスト環境を分けてスクリプトを運用。
  • 例外処理の強化: エラーケースを網羅し、処理の中断を防止。
  • ログの定期監視: 自動化されたプロセスの状態を定期的に確認。

まとめ


PowerShellを活用した定期的なデータ更新の自動化により、手動作業を排除し、効率的な運用を実現できます。Windowsタスクスケジューラとの組み合わせやログ・通知機能を追加することで、さらに信頼性の高いプロセスが構築できます。次項では、この記事の内容を簡潔にまとめます。

まとめ

本記事では、PowerShellを活用してSnowflakeのStageを作成し、大量データのロードを効率化する方法を解説しました。SnowflakeのStage機能の基本概念から、PowerShellによる認証設定、Stageの作成、データロード、エラー処理、自動化の応用例までを詳しく説明しました。

PowerShellスクリプトを使用することで、データ処理の手間を削減し、定期的なデータ更新やトラブルシューティングも効率化できます。この手法を導入することで、日常業務の効率が大幅に向上するだけでなく、エラーや作業ミスを防ぎ、安定した運用が実現可能です。

本記事の内容を参考に、ぜひPowerShellとSnowflakeを組み合わせたデータ管理プロセスを構築してみてください。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次