はじめに
前回の記事「Azure でデータ基盤を構築・可視化」では、Azure Blob Storage → Data Factory → Azure SQL Database → Power BI の構成で、手動実行を前提とした可視化までの手順を紹介しました。
具体的には、Blob の CSV を ADF で SQL に取り込み、Power BI から参照・可視化するところまでを GUI 中心に確認しています。
本記事では、前回の構成を発展させ、「Blob に CSV を置くだけ」で自動的に SQL へ反映され、Power BI からすぐ確認できるパイプラインを構築します。エンドユーザーは raw/inbox/
にファイルをアップロードするだけでよく、運用の手間を最小化できます。
はじめに この記事では、Azure を利用してデータ基盤を構築し、可視化する手順について紹介します。具体的には、Azure Blob Storage に CSV データを格納し、Data Factory を用いて Azure SQL[…]
全体アーキテクチャ
構成概要は以下の通りです。
ユーザー → raw/inbox/ に CSV アップロード
ADF(Blob Created イベント)→ パイプライン起動
ADF Copy → Azure SQL Database(サーバーレス) に追記
Power BI(DirectQuery/Import)で可視化
ストレージ(ADLS Gen2)の準備
ストレージアカウントの作成
まずは Azure 上にデータを保存するためのストレージアカウントを作成します。
Azure ポータル →「ストレージアカウント」→「作成」
入力項目
リソースグループ:
rg-lake-demo
(既存でも可)ストレージアカウント名:
stlakedemo01
リージョン:
Japan East
パフォーマンス:Standard
冗長性:LRS(ローカル冗長)
詳細設定:階層型名前空間(HNS)を 有効化
作成 → デプロイ完了を待つ
コンテナとフォルダ構成の準備
次に、CSV を置くためのコンテナとフォルダを用意します。
作成したストレージアカウントを開く
左メニュー「コンテナー」→「+ コンテナー」
名前:
raw
パブリックアクセスレベル:非公開(推奨)
raw
コンテナが作成されたら、さらにサブフォルダとしてinbox
を作成
フォルダ階層イメージ:
raw/
└── inbox/

テスト用 CSV のアップロード
動作確認のため、サンプルの CSV ファイルを inbox
フォルダにアップロードします。
raw
コンテナを開き、inbox
フォルダを選択「アップロード」→ ファイル選択(例:
demodata.csv
)アップロード完了を確認
テスト用 CSV のサンプル(1行目はヘッダ行):
Rally,Server,Winner,ServeType,Outcome,Axis,SpinClass,Length,Course,Contact,Set,match_id,created_at,player,opponent
1,Alice,Alice,Forehand,Rally won,Right,Topspin,Short,Forehand,None,1,M001,2025/9/30 10:00,Alice,Bob
2,Bob,Alice,Backhand,Rally lost,Left,Backspin,Long,Backhand,Edge,1,M001,2025/9/30 10:01,Alice,Bob
- ユーザーが操作するのは
raw/inbox/
のみ - 後続の ADF トリガーは、この
inbox
にファイルが置かれたら自動実行するよう設定 - 運用では、エンドユーザーはただ CSV を放り込むだけでよい設計になる
SQL Database(サーバーレス)の準備
サーバーレス構成でデータベース作成
データを格納するための Azure SQL Database を、サーバーレス構成で用意します。
Azure ポータル →「SQL データベース」→「作成」
設定例:
リソースグループ:
rg-lake-demo
データベース名:
sqlauto
サーバー:新規作成 → 名前
sqlsrv-auto01
(場所:Japan East)コンピューティング:サーバーレス を選択
自動一時停止:ON(1時間の既定でOK)
ストレージ:標準でOK(検証用途のため)
「確認と作成」→「作成」
デプロイ完了後、SQL Database の概要ページが表示されます。
ここに「SQL Database 作成画面のスクショ」を添付

ファイアウォール設定
ローカル PC や ADF から接続できるように、ネットワーク設定を変更します。
「サーバーのファイアウォールの設定」→「現在のクライアント IP を追加」
「Azure サービスおよびリソースがこのサーバーにアクセスすることを許可」= ON

テーブル定義
アップロードされた CSV データを格納するためのテーブルを作成します。
SQL Database 画面 → 左メニュー「クエリ エディター (プレビュー)」を開く
ログイン(SQL 認証 or Azure AD 認証)
以下のクエリを実行し、テーブルを作成
CREATE TABLE dbo.TableTennisDemo (
Rally INT,
[Server] NVARCHAR(50),
Winner NVARCHAR(50),
ServeType NVARCHAR(100),
Outcome NVARCHAR(100),
Axis NVARCHAR(50),
SpinClass NVARCHAR(50),
[Length] NVARCHAR(50),
Course NVARCHAR(50),
Contact NVARCHAR(50) NULL,
SetNumber INT,
match_id NVARCHAR(50),
created_at DATETIME2,
player NVARCHAR(50),
opponent NVARCHAR(50)
);
-- 大量データを扱う場合は、列ストアインデックスを付与(任意)
CREATE CLUSTERED COLUMNSTORE INDEX CCI_TableTennisDemo
ON dbo.TableTennisDemo;

動作確認
テーブル作成後、次のクエリを実行すると確認できます。
-- DB名とログインユーザー確認
SELECT DB_NAME() AS dbname, SUSER_SNAME() AS login_name, SYSDATETIME() AS now;
-- テーブルが存在するか確認
SELECT COUNT(*) AS cnt
FROM sys.tables
WHERE name = 'TableTennisDemo';
想定される結果:
dbname
にsqlauto
が表示されるlogin_name
にログイン中のユーザーが表示されるcnt = 1
で、テーブルが存在していることを確認

Data Factory の構築
Data Factory インスタンス作成
Azure ポータル →「Data Factory」→「作成」
設定例:
リソースグループ:
rg-lake-demo
名前:
adf-lakedemo
リージョン:Japan East
デプロイ完了後、「スタジオで開く」から ADF Studio を起動します。

Linked Services(接続設定)
データソース(ADLS Gen2)と宛先(SQL Database)を接続します。
ADF Studio → 左ペイン「管理」→「Linked services」→「+ 新規」
A. ADLS Gen2
種類:Azure Data Lake Storage Gen2
名前:
ls_adls
認証:検証では「アカウントキー」でOK
アカウント:
stlakedemo01
B. Azure SQL Database
種類:Azure SQL Database
名前:
ls_sqlauto
サーバー:
sqlsrv-auto01.database.windows.net
DB:
sqlauto
認証:SQL 認証(sqladmin / 作成時のPW)

データセット作成
A. ソース(CSV on ADLS)
[オーサリング] →「+」→「データセット」
種類:Azure Data Lake Storage Gen2 → DelimitedText
設定:
名前:
ds_raw_csv
Linked service:
ls_adls
File system(=コンテナ):
raw
先頭行をヘッダーとして使用:ON
「パラメータ」タブで追加:
folder
(String)file
(String)
「接続」タブ → File path を以下に設定:
Directory = @{dataset().folder}
File = @{dataset().file}

B. シンク(SQL Database)
「+ データセット」→「Azure SQL Database」
設定:
名前:
ds_sql_tennis
Linked service:
ls_sqlauto
テーブル:
dbo.TableTennisDemo

パイプライン作成
[オーサリング] →「+」→「パイプライン」
名前:
pl_inbox_to_sql
パラメータ追加:
p_folder
(String)p_file
(String)

Copy Data アクティビティの設定
パイプラインキャンバスに「Copy data」を配置
ソース:
ds_raw_csv
Parameters:
folder =
@pipeline().parameters.p_folder
file =
@pipeline().parameters.p_file
シンク:
ds_sql_tennis

マッピング修正(Set → SetNumber)
Copy Data →「マッピング」タブを開く
「スキーマのインポート」をクリック → サンプル CSV のパスを指定して列を読み込み
p_folder
→inbox
p_file
→demodata.csv
自動マッピング後に Set → SetNumber を手動で修正

発行
左上の「すべて発行」をクリックして設定を保存。
これで Blob → SQL のコピー基盤が完成しました。
イベントトリガー設定
トリガー作成
ADF Studio → 左ペイン「管理 (Manage)」→「トリガー (Triggers)」→「+ 新規」
設定例:
名前:
trg_inbox_to_sql
種類:ストレージイベント (Blob created)
ストレージアカウント:
stlakedemo01
コンテナ:
raw
Blob パス末尾フィルター:
.csv

パイプラインとの関連付け
トリガー作成画面で「パイプラインを選択」→
pl_inbox_to_sql
を選択パラメータに以下を設定:
p_file = @{triggerBody().fileName}
p_folder = @{triggerBody().folderPath}
p_folder = @{replace(triggerBody().folderPath, 'raw/', '')}

有効化
「作成」→「発行」
トリガー一覧で
trg_inbox_to_sql
の状態が「有効」になっていることを確認
動作イメージ
ユーザーが
raw/inbox/
にdemodata.csv
をアップロードイベントトリガーが発火 → パイプライン
pl_inbox_to_sql
が自動実行データが SQL Database に取り込まれる
Power BI との連携
DirectQuery で SQL に接続
Power BI Desktop →「データの取得」→「Azure SQL Database」
設定例:
サーバー:
sqlsrv-auto01.database.windows.net
データベース:
sqlauto
接続モード:DirectQuery(リアルタイム参照)

レポート作成
取り込んだ dbo.TableTennisDemo
テーブルを利用して可視化を行います。

リロード方法
Power BI の更新方法は大きく3種類あります。
手動更新 (Refresh)
Power BI Desktop 上で [更新] ボタンをクリックAuto page refresh(Premium 機能)
数分ごとに自動更新が可能(DirectQuery 利用時に便利)Import + スケジュール更新
Import モードを選んだ場合は Power BI Service 上でスケジュール更新設定が可能
動作確認
新しい CSV を配置
raw/inbox/
に新しい CSV ファイルをアップロード例:
demodata_new.csv

参考:demodata_new.csv(中身)
Rally,Server,Winner,ServeType,Outcome,Axis,SpinClass,Length,Course,Contact,Set,match_id,created_at,player,opponent
1,Alice,Alice,Forehand,Winner,Right,Topspin,Short,Forehand,None,1,M001,2025-09-30 10:00:00,Alice,Bob
2,Bob,Alice,Backhand,Error,Left,Backspin,Long,Backhand,Edge,1,M001,2025-09-30 10:01:00,Alice,Bob
3,Charlie,Charlie,Reverse sidespin serve,Service ace,Right,Topspin,Half-long,Middle,,2,M002,2025-10-01 09:00:00,Charlie,Dana
4,Dana,Charlie,Vertical-spin serve,Rally won,Left,Non-backspin,Long,Forehand,,2,M002,2025-10-01 09:05:00,Charlie,Dana
ADF モニターで確認
ADF Studio → [Monitor] → パイプライン実行履歴を確認
状態が Succeeded であることをチェック

SQL / Power BI で最新化を確認
- SQL Database で行数を確認
SELECT COUNT(*) FROM dbo.TableTennisDemo;
Power BI のレポートで新しいデータが反映されていることを確認

データ削除(クリーンアップ)
データ検証を繰り返すうちに、既存データをリセットしたい場合があります。
ここでは、SQL 側のデータ削除(手動・自動)を行う 2 つの方法を紹介します。
方法①:SQL クエリで手動削除
Azure ポータルの クエリエディター(プレビュー) から実行します。
■すべてのデータを削除する場合
TRUNCATE TABLE dbo.TableTennisDemo;
■特定の条件で削除する場合(例:過去の日付データのみ削除)
DELETE FROM dbo.TableTennisDemo
WHERE created_at < '2025-09-30';
💡 TRUNCATE TABLE はテーブルを高速にリセットでき、主キーや ID シーケンスも初期化されます。
方法②:ADF パイプラインで削除処理を自動化する
「Copy Data」アクティビティの前段に、Stored Procedure Activity または Script Activity を追加します。これにより、毎回ファイルアップロード時に既存データを削除してから新しい CSV をロードできます。
■例:すべて削除するスクリプト
TRUNCATE TABLE dbo.TableTennisDemo;
💡この方法を組み込んでおくと、テストや日次自動取込時に常にクリーンな状態からロードできるため、再現性の高い検証・運用が可能になります。
感想
今回の仕組みにより、ユーザー側は 「CSV をアップロードするだけ」 でデータが自動的に SQL に取り込まれ、Power BI で最新の可視化が可能になりました。
運用コストが低い
複雑な操作は不要で、ユーザーはストレージにファイルを置くだけ。
Azure Functions や Synapse と比べても、ADF のイベントトリガー+SQL サーバーレスという組み合わせは運用負荷が低く、保守もしやすい構成です。
導入コストも抑えられる
今回のような構成であれば、ほぼ GUI 操作のみで構築可能です。
コード開発や複雑なスクリプトが不要なため、短期間で導入できる点も大きなメリットです。
拡張が容易
フォルダ規約を拡張したり、SQL テーブルを増やすことで、他のデータにも簡単に対応可能です。
さらに、Power BI のスケジュール更新や API を活用することで、より高度な自動化にも発展させられます。
以上、最後までお読みいただきありがとうございました。