1. はじめに企業では、日々の業務を通じて多くのデータが蓄積されています。一方で、現場で作成・運用されるExcelなどのデータと、データ基盤やデータベース上に蓄積されたデータが分断され、確認作業や突き合わせ作業を手作業で行っているケースも少なくありません。このような業務では、現場で発生するデータをデータ基盤に取り込み、既存データと組み合わせて確認できる仕組みを作ることで、作業の効率化や確認精度の向上が期待できます。今回は、Snowflake上で動作するWebアプリをPythonで簡単に作成できる「Streamlit in Snowflake」を活用し、現場で作成した棚卸しExcelをアップロードして、Snowflake上の理論在庫データと突き合わせ、在庫差異を確認できるようなアプリのユースケースをご紹介します。2. 今回作成するユースケースについて2.1 アプリ概要現場で数えた実棚卸テストデータをStreamlit in Snowflakeアプリでアップロードし、Snowflake上の理論在庫データと突き合わせて、在庫差異を確認するアプリです。以下が完成物になります。2.2 業務シナリオ小売業や倉庫業務では、システム上の在庫数と、現場で実際に数えた在庫数が一致しているかを定期的に確認する必要があります。今回のユースケースでは、Snowflake上にPOSや在庫管理システムから連携された理論在庫データが蓄積されている想定です。一方、現場で実施した棚卸し結果は、店舗ごとにExcelで作成される想定です。今回はStreamlit in Snowflakeを使って、棚卸しExcelをアップロードし、Snowflake上の理論在庫データと突き合わせて、商品別の在庫差異を確認できるアプリを作成します。2.3 画面構成セクション内容Excelアップロード実棚卸データをアップロードする在庫差異確認Snowflake上の理論在庫データと実棚卸データを比較するExcelダウンロード差異確認結果をExcelでダウンロードする2.4 テーブル設計INVENTORY_SNAPSHOTSnowflake上に事前投入しておく理論在庫テーブルです。カラム名型説明SNAPSHOT_DATEDATE在庫基準日STORE_IDVARCHAR店舗IDSTORE_NAMEVARCHAR店舗名PRODUCT_IDVARCHAR商品IDPRODUCT_NAMEVARCHAR商品名SYSTEM_STOCK_QTYNUMBERシステム上の在庫数PHYSICAL_INVENTORY_COUNTSStreamlit in Snowflakeからアップロードする実棚卸テーブルです。(アップロードするExcelも同じ列構成となります)カラム名型説明COUNT_DATEDATE棚卸日STORE_IDVARCHAR店舗IDSTORE_NAMEVARCHAR店舗名PRODUCT_IDVARCHAR商品IDPRODUCT_NAMEVARCHAR商品名ACTUAL_STOCK_QTYNUMBER実際に数えた在庫数UPLOADED_ATTIMESTAMP_NTZアップロード日時UPLOADED_BYVARCHARアップロード者2.5 処理の流れSnowflakeに理論在庫データを事前投入するStreamlit in Snowflakeアプリで実棚卸Excelをアップロードするアップロードした実棚卸データをSnowflakeに登録する理論在庫データと実棚卸データを突き合わせる商品別に在庫差異を確認する差異確認結果をExcelでダウンロードする※ 差異の判定について理論在庫数と実棚卸数を比較し、差異数量を算出します。ACTUAL_STOCK_QTY - SYSTEM_STOCK_QTY AS DIFF_QTY差異が0であれば一致、0以外であれば差異ありとして扱います。2.6 テストデータ今回のテストデータは、理論在庫データ100行、実棚卸データ100行で構成します。そのうち、実棚卸データ側で理論在庫数と異なる商品を5件だけ用意し、残り95件は一致するようにしています。これにより、アプリ上では「100件中5件だけ差異がある」という現実に近い確認結果を表示できます。3. Snowflake側の準備ソースコードは以下になります。ソースコード3.1 データベース・スキーマ作成GitHubからリポジトリをクローンしたら、sql/init.sql を開きSQLを全てコピーします。Snowflakeのワークスペースに移動後、新規追加からSQLファイルを選び、コピーしたSQLを貼り付けます。データベース名をご自身の環境に合わせて変更し、全選択後にSQLを実行します。※ この例ではデータベース名を DEV_DATABASE としました。データベースエクスプローラーに移動し、クエリ実行先のデータベース ➡ INVENTORY_DIFF_APP スキーマを選択し、二つのテーブルが作成されていることを確認します。3.2 理論在庫データ投入テーブルの確認が完了したら、INVENTORY_SNAPSHOT テーブル(理論在庫テーブル)を選択し、右上の データをロード を押下します。※ このデータは本来、POSや在庫管理システムから追加される想定です。ダイアログが表示されるので、中央の 閲覧 を選択し、先ほどクローンしたリポジトリの data/inventory_snapshot_seed.csv を選択します。アップロード後 次へ を押下し、アップロードされたデータを確認後、右下の ロード を押下します。ロード後、ダイアログが表示されるので テーブルの詳細を表示 を押下後、データプレビュー タブを選択し、アップロードされたデータを確認します。4. 動作確認前に理解しておきたい内容※ 記事内ではコードの詳細な解説は行いません。環境構築手順についてはクローンしたリポジトリの README.md をご覧ください。4.1 Snowflake CLIについてSnowflake CLIは、ローカルからSnowflake上のオブジェクトを操作するためのCLIです。 今回の記事では、Streamlit in Snowflakeアプリのデプロイに使用します。今回作成したユースケースで使用している主要なコマンドは以下になります。コマンド説明参考リンクsnow Snowflake CLIの実行コマンドhttps://docs.snowflake.com/ja/developer-guide/snowflake-cli/command-reference/snowsnow connection addSnowflakeへの接続情報を登録するhttps://docs.snowflake.com/ja/developer-guide/snowflake-cli/command-reference/connection-commands/add-connectionsnow connection test接続確認を行うhttps://docs.snowflake.com/ja/developer-guide/snowflake-cli/command-reference/connection-commands/test-connectionsnow streamlit deployStreamlit in Snowflakeへアプリをデプロイするhttps://docs.snowflake.com/ja/developer-guide/snowflake-cli/command-reference/streamlit-commands/deploy参考:Snowflake CLI4.2 config.toml についてSnowflake CLIで snow connection add コマンドを使用して接続を追加した際には、~/.config/snowflake 配下にある config.toml に記載されます。ここに記載された接続情報は、テスト接続時やデプロイ時等の、 snow コマンドがSnowflakeへ接続する際に使われることになります。接続方法には様々な種類があり、プライベートキーファイルを使用した認証、OAuthを使用した認証、MFAを使用した認証、SSOを使用した認証などがあります。今回は、ローカル環境からSnowflake CLIを実行しやすいように、プライベートキーファイルを使用したキーペア認証を採用しました。config.tomlの記載例[connections.your_connection_name]account = "YOUR_ACCOUNT"user = "YOUR_USER"authenticator = "SNOWFLAKE_JWT"private_key_file = "~/.ssh/snowflake/<your_private_key_name>.p8"参考1:Snowflake CLI の構成参考2:認証にプライベートキーファイルを使用する4.3 .streamlit/secrets.toml についてプロジェクトルートフォルダ直下に設置する .streamlit/secrets.toml には、アプリがSnowflakeに接続するための情報を記載します。機密ファイルのため、Git追跡されていません。そのため、動作確認時はご自身でフォルダ・ファイルを作成していただく必要があります。secrets.tomlの記載例[connections.snowflake]account = "YOUR_ACCOUNT"user = "YOUR_USER"role = "YOUR_ROLE"warehouse = "YOUR_WAREHOUSE"database = "YOUR_DATABASE"schema = "INVENTORY_DIFF_APP"private_key_file = "~/.ssh/snowflake/<your_private_key_name>.p8"参考1:シークレットを管理し、Streamlitアプリを設定する4.4 snowflake.yml についてプロジェクトルートフォルダ直下に設置されている snowflake.yml は、プロジェクト内の複数のファイルやオブジェクトを定義するための、プロジェクト定義ファイルです。こちらのファイルはSnowflakeへのデプロイ時に必要となります。今回作成したユースケースで使用している主要な設定項目は以下になります。項目説明type種類を指定します。今回は streamlit となります。identifierSnowflake上に作成するStreamlitアプリ名です。Snowflake上で実際のアプリ名として表示されます。query_warehouseアプリをホストするWarehouseを指定します。main_fileエントリーポイントとなるPythonファイルを指定します。artifactsデプロイ対象のファイルを指定します。snowflake.ymlの記載例definition_version: 2entities: sis-inventory-diff-app: type: streamlit identifier: INVENTORY_DIFF_APP query_warehouse: STREAMLIT_WH main_file: app.py artifacts: - app.py - environment.yml参考1:プロジェクト定義ファイルについて参考2:Streamlitアプリのプロジェクト定義の作成4.5 environment.yml について同じくプロジェクトルートフォルダ直下に設置されている environment.yml はStreamlit in Snowflake上で動かすための依存関係定義ファイルです。environment.ymlの記載例name: sis-inventory-diff-appchannels: - snowflakedependencies: - streamlit=1.52.2 - pandas=2.* - openpyxl - xlsxwriter今回は管理をなるベく楽にするために、ウェアハウスランタイムを使用しています。ローカルでの依存関係の管理はPoetryで行っているため、本番運用等で厳密なパッケージ環境をそのまま再現したい場合には、コンテナランタイムの使用をお勧めします。ウェアハウスランタイムアプリはオンデマンド(使用される度に用意)で実行され、閲覧者ごとに個別のアプリインスタンスが作成されます。常時稼働ではないため、使用頻度が少ないケースでは費用が抑えられたり、管理が楽というメリットがあります。一方で、Snowflake側で用意されているライブラリしか使用できなかったり、複数のユーザーが頻繁に使用する場合には費用が高くなってしまうといったデメリットがあります。コンテナランタイムアプリは長時間稼働するサービスとして提供され、全閲覧者で共有される専用インスタンスが作成されます。頻繁にアクセスされるアプリの場合、費用対効果が高くなることや、アプリに素早く接続できる等のメリットがあります。一方で、専用のサーバーをずっと動かし続けるため、誰もアプリを見ていなくても基本的にはサーバーの費用がかかり続けてしまうといったデメリットもあります(3日使用されない場合は停止されます)。参考1:Streamlitアプリの依存関係を管理する参考2:Streamlitアプリのランタイム環境5. ローカル環境での動作確認とデプロイ5.1 ローカル環境での動作確認README.md の内容に沿って環境構築ができたら、以下のコマンドを実行してローカル環境で動作確認を行います。poetry run streamlit run app.pyアドレスバーにURLを打ち込んでアプリを開きます。Browse files ボタンを押下し、data/physical_inventory_counts_upload.xlsx をアップロードします。プレビューでデータが問題なく読み込まれたことを確認し、Snowflakeに登録する を押下します。上部メニューの 在庫差異確認 から一致しているデータ・差異のあるデータを確認します。上部メニューの Excelダウンロード から画面遷移し、差異ありのみダウンロード にチェックをつけて、Excelをダウンロード を押下します。ダウンロードしたExcelファイルを開き、データを確認します。開発環境からSnowflakeと接続し、データの登録・データの参照・Excelダウンロードが問題なく行われることを確認することができました。5.2 デプロイとSnowflake上での動作確認ローカル環境での動作確認が完了したら、以下のコマンドを実行してSnowflake環境にデプロイを行います。※ your(YOUR)... の部分はご自身の環境に合わせて変更してください。poetry run snow streamlit deploy --replace --prune --open -c your_connection_name --database YOUR_DATABASE --schema INVENTORY_DIFF_APP成功した場合は以下のようなメッセージが表示されるので、URLからブラウザでアプリの画面を開いてください。Snowflake上でアプリが開き、ローカル環境と同じ挙動になることを確認してください。6. まとめ今回は、Streamlit in Snowflakeを使って、現場で作成した棚卸しExcelをアップロードし、Snowflake上の理論在庫データと突き合わせて在庫差異を確認するアプリを作成しました。この構成により、Excelなどで管理されている現場データをSnowflakeに取り込み、既存のデータ基盤上のデータと組み合わせて確認・分析できるようになります。Streamlit in Snowflakeを活用することで、Snowflake上のデータを外部に大きく移動させることなく、データ登録・確認・ダウンロードを行う業務アプリを比較的シンプルに構築できます。今回の棚卸し差異確認アプリは一例ですが、同じ構成は以下のような業務にも応用できます。Snowflake上の集計結果をExcelで出力する業務Snowflake上のデータマート内のデータを確認する業務ExcelのデータをSnowflake上にアップロードする業務データ基盤に蓄積されたデータを、現場業務に近い形で活用する手段として、Streamlit in Snowflakeは有効な選択肢の一つになりそうです。CLOVE合同会社は、企業のデータ活用を推進するための戦略策定、データ基盤構築、データ分析、AI活用支援を提供するコンサルティング会社です。 データ活用の専門家として、マーケティング、営業、業務効率化など幅広い領域で支援を行っております。貴社の課題や目的に応じた最適な設計をご提案しますので、ご興味がありましたらぜひお問い合わせフォームからお気軽にご相談ください。