はじめに
私はデータ基盤の運用保守に携わっており、主にバッチ処理まわりの保守や追加開発を担っています。
結論から言うと、別組織のアカウントへデータを共有するときは、Private Listing(相手を限定した非公開リスティング)を使い、SQL では CREATE SHARE → CREATE EXTERNAL LISTING の2段で組み立てます。すでにある Direct Share(共有オブジェクト)を裏付けにして、それを Private Listing に「変換」する形です。
この記事は、以前公開した「Snowflake Private Listing × Dynamic Table でアカウントをまたぐデータ共有を自動化する」(全体構成=結合結果を Secure View にして共有し返す話)で、共有し返す部分を Snowsight(画面操作)で行った箇所を、SQL で書くとどうなるかをまとめたものです。
実は私のケースは、同じ会社でも部署ごとに Snowflake 組織が分かれていて、アカウント間の共有は「組織外(別組織)」でした。組織内か組織外かで使うコマンドが変わり(組織外は CREATE EXTERNAL LISTING)、本記事はこの組織外を扱います。同一組織内の場合は、別記事「Snowflakeの組織内データ共有をSQLで作る — Share と Organization Listing の2層」にまとめています。
実案件では共有の作成は Snowsight(Provider Studio)で行いました。本記事の SQL は、その画面手順を SQL に置き換えると各ステップがどのパラメータに対応するかを、公式ドキュメントで裏取りして整理したものです。
まず確認:本当に「組織外」か
組織内か組織外かで使うコマンドが変わります。**同一企業でも、部署ごとに別の Snowflake 組織なら「組織外」**です。両方のアカウントで組織名を出し、一致するかで判断します。
-- 共有元・共有先それぞれのアカウントで実行
SELECT CURRENT_ORGANIZATION_NAME();
- 一致すれば組織内 →
CREATE ORGANIZATION LISTING(別記事「組織内版」)。 -
異なれば組織外 →
CREATE EXTERNAL LISTING(本記事)。
前提・環境
- 共有元と共有先が別組織であること(同一企業でも別組織なら本記事の手順)。
- 共有対象は Secure View(Share に載せられるのは既定でセキュアオブジェクトのみ。非セキュアビューを載せるには Share 側の設定が要ります)。
- 権限:Share を作る
CREATE SHARE、リスティングを作るCREATE LISTINGの各グローバル権限(既定はACCOUNTADMIN)。オーナーロールを先に決めて付与しておく考え方は、組織内の場合と共通です。 - プロバイダープロファイル・規約:無料/有料の オフプラットフォーム Private Listing は、Snowflake の審査もプロバイダー/コンシューマー規約への同意も不要です(Marketplace 公開のときだけ必要)。
- SQL の実行場所:Snowsight の SQL ワークシートや
snowCLI など。
組織内(Organization Listing)との違い
| 組織内 | 組織外(本記事) | |
|---|---|---|
| SQL コマンド | CREATE ORGANIZATION LISTING |
CREATE EXTERNAL LISTING |
manifest の organization_profile
|
INTERNAL |
使わない(profile は任意) |
| 対象指定 | organization_targets |
targets.accounts(Org.Account 形式) |
| Snowflake 審査 | 不要 | private/off-platform は不要(Marketplace 公開時のみ要) |
手順①:Secure View を用意し、Direct Share を作る
まず「中身」である Share を作り、共有する Secure View を付与します。ここは組織内と同じです。
-- 共有の中身(Direct Share の実体)を作る
CREATE SHARE my_share;
GRANT USAGE ON DATABASE my_db TO SHARE my_share;
GRANT USAGE ON SCHEMA my_db.my_schema TO SHARE my_share;
GRANT SELECT ON VIEW my_db.my_schema.my_secure_view TO SHARE my_share;
この Share を、次の手順で Private Listing の裏付けにします。
手順②:CREATE EXTERNAL LISTING で Private Listing にする
CREATE EXTERNAL LISTING は、手順①の Share を裏付けにして、対象アカウントなどを manifest(YAML)で宣言します。Snowsight の「Create Listing」画面の各入力が、そのまま manifest の項目に対応します。
CREATE EXTERNAL LISTING my_private_listing
SHARE my_share AS $$
title: "会員クロス集計(主キーのみ)" -- 必須(画面の「名前/タイトル」)
subtitle: "属性A×属性Bの該当会員" -- 任意(private。画面の「サブタイトル」)
description: "属性A・B両方を持つ会員の主キー一覧。結合結果を Secure View で提供。" -- 必須
listing_terms: -- 必須
type: "OFFLINE"
targets:
accounts: ["<共有先のOrg名>.<共有先のAccount名>"] -- 画面の「Who can access」。最大100
$$
PUBLISH = TRUE;
-- 無料 … pricing_plans を書かない / 有料 … pricing_plans: を追加
Snowsight 手順 → SQL 対応表
貼り付けでよく見る画面手順が、SQL のどこに効くかの対応です。
| Snowsight の手順 | SQL / manifest での対応 |
|---|---|
| Provider Studio を開く | UI 固有。SQL では CREATE LISTING 権限を持つロールで実行するだけ |
| Create Listing、名前を入力 | CREATE EXTERNAL LISTING <name> |
| subtitle を入力・profile を選択 | manifest subtitle: / profile:(どちらも private では任意) |
| Product type で既存の secure share を選択 |
... SHARE <share_name>(個別オブジェクトでなく Share を裏付けに) |
| Access type = Free | manifest に pricing_plans を書かない(=無料)。有料は pricing_plans: を定義 |
| Who can access にアカウント識別子 | manifest targets.accounts: ["<Org>.<Account>"]
|
| 残りのフィールドを設定 | manifest 必須の title / description / listing_terms
|
| Submit for approval and publishing |
PUBLISH = TRUE(審査は REVIEW で制御。private/off-platform は Marketplace 審査に出さない) |
「無料設定」は独立したフラグではありません。 manifest に pricing_plans を持たせない状態が「無料」で、有料にするときだけ pricing_plans を足す、という効き方です。画面の Access type = Free / Paid は、この有無に対応します。
手順③:共有先(消費側)でデータベースとして参照する
公開された Private Listing は、共有先のアカウントで CREATE DATABASE ... FROM LISTING を使ってマウントします。
-- 消費側アカウントで実行
CREATE DATABASE my_shared_db
FROM LISTING '<listing_global_name>';
SELECT * FROM my_shared_db.my_schema.my_secure_view;
<listing_global_name> は、対象のリスティングを一意に指すグローバル名です。値は消費側に届いたリスティングから確認できます(後述の SHOW AVAILABLE LISTINGS)。
作成したオブジェクトを確認する
Share と Listing はそれぞれ SHOW / DESCRIBE で確認できます。
-- 提供側:Share
SHOW SHARES; -- kind が OUTBOUND のものが自分の共有。listing_global_name 列も見える
DESCRIBE SHARE my_share; -- Share に載っているオブジェクト
-- 提供側:Listing
SHOW LISTINGS; -- USAGE / MODIFY / OWNERSHIP を持つリスティング
DESCRIBE LISTING my_private_listing;
-- 消費側:自分に届いているリスティング
SHOW AVAILABLE LISTINGS;
つまずきやすいポイント
-
組織内と組織外でコマンドが違う。組織外は
CREATE EXTERNAL LISTING、組織内はCREATE ORGANIZATION LISTING。まずCURRENT_ORGANIZATION_NAME()で見分けます。 -
「無料」は
pricing_plansの有無。独立フラグではありません。 -
targets.accountsはOrg.Account形式(アカウントロケータではなく組織名+アカウント名)。最大100件。 - 共有できるのは既定でセキュアオブジェクトのみ。Secure View で絞ってから共有します。
-
権限:
CREATE SHAREとCREATE LISTINGが要ります。SYSADMINなどには既定で付いていません。
まとめ・学び
- 組織外アカウントへの共有は、Direct Share(中身)を作り、
CREATE EXTERNAL LISTINGで Private Listing 化する2段で SQL に落とせます。CREATE SHARE→GRANT ... TO SHARE→CREATE EXTERNAL LISTING→ 消費側CREATE DATABASE ... FROM LISTING、という流れです。 - 画面の入力項目は、そのまま manifest の項目に対応します。特に 「無料」は
pricing_plansを書かないことで効く、という対応を押さえると、画面と SQL を行き来しやすくなります。 - 同じ会社でも別組織なら組織外。最初に
CURRENT_ORGANIZATION_NAME()で見分けるのが、コマンド選択の入口です。
参考リンク(公式ドキュメント)
- Create and publish a listing(Direct Share の private listing 化を含む)
- CREATE LISTING
- Listing manifest reference(manifest の各フィールド)
- Manage listings with SQL as a provider - examples
- Create and configure shares(CREATE SHARE と Secure View 共有の制約)
- Use secure objects to control data access(セキュアオブジェクト共有の推奨)
- Introduction to organizations(組織の概念)
- CURRENT_ORGANIZATION_NAME