❄️

Snowflakeと直接接続できるrow zeroという表計算ツールさわってみた

に公開

まえがき

今週Snowflake Summit 2025がありました!
当然自分はいけなかったので、X(旧Twitter)上のTLに流れてきた機能を見ていたのですが、すぐ試せそうなrow zeroというツールについて今回触ってみることにしました。
このツールはSnowflake の機能というわけではなく、ExcelやGoogleスプレッドシートのような表計算ツールです。
ただし高速化されていたりSnowflakeとデータを直接やりとりできる...という点で紹介されていたようです。
通常Excelなどではローカルに保存・複製がいっぱいできてどれが最新のデータかわからない&個人がデータを溜め込んでしまう(データのサイロ化)という流れはよく目にすると思います。
データを一元化しつつデータウェアハウスと直接やりとりできる表計算ツールを実現するようなものになるのではと思い今回さわってみました。

公式サイトなど

[rowzero]

https://rowzero.io/
https://www.youtube.com/@Row-Zero

[Snowflake Summit 2025]

https://www.youtube.com/watch?v=gJf39VG87O8
https://www.youtube.com/watch?v=xXpqQk0CBZY

サインアップ

なにはともあれまずはサインアップから
https://rowzero.io/

Googleアカウントがあればそちらでサインアップできるようになっています。(ロゴがシンプルでかっこいいですね)

ログインするとすぐに以下のような画面が出てきました!(シンプル)

容量の大きいparquetファイルを「row zero」で読む。

実はちょっとだけ以下のkaggleコンペに参加中なんですが...
https://www.kaggle.com/competitions/drw-crypto-market-prediction

なんとtestデータが3.6GBという...😅(trainも同じくらいあります。)
ちなみに列数約1000列・行数約53万行でした。

行列数確認用のコード

行数確認

import duckdb

con = duckdb.connect(database=":memory:")
print(con.sql(f"SELECT COUNT(*) FROM 'xxxxxxxxxx/test (1).parquet'"))
┌──────────────┐
│ count_star() │
│    int64     │
├──────────────┤
│       538150 │
└──────────────┘

約53万行...😅
列数は以下のコードで確認します。(普通にSELECT * FROM でもいいんですが以下の方が速いので)

import duckdb

con = duckdb.connect(database=":memory:")
print(con.sql(f"DESCRIBE '/Users/nk/Downloads/test (1).parquet'"))
┌─────────────┬─────────────┬─────────┬─────────┬─────────┬─────────┐
│ column_name │ column_type │  null   │   key   │ default │  extra  │
│   varchar   │   varchar   │ varchar │ varchar │ varchar │ varchar │
├─────────────┼─────────────┼─────────┼─────────┼─────────┼─────────┤
│ bid_qty     │ DOUBLE      │ YES     │ NULL    │ NULL    │ NULL    │
│ ask_qty     │ DOUBLE      │ YES     │ NULL    │ NULL    │ NULL    │
│ buy_qty     │ DOUBLE      │ YES     │ NULL    │ NULL    │ NULL    │
│ sell_qty    │ DOUBLE      │ YES     │ NULL    │ NULL    │ NULL    │
│ volume      │ DOUBLE      │ YES     │ NULL    │ NULL    │ NULL    │
│ X1          │ DOUBLE      │ YES     │ NULL    │ NULL    │ NULL    │
│ X2          │ DOUBLE      │ YES     │ NULL    │ NULL    │ NULL    │
│ X3          │ DOUBLE      │ YES     │ NULL    │ NULL    │ NULL    │
│ X4          │ DOUBLE      │ YES     │ NULL    │ NULL    │ NULL    │
│ X5          │ DOUBLE      │ YES     │ NULL    │ NULL    │ NULL    │
│ ·           │   ·         │  ·      │  ·      │  ·      │  ·      │
│ ·           │   ·         │  ·      │  ·      │  ·      │  ·      │
│ ·           │   ·         │  ·      │  ·      │  ·      │  ·      │
│ X882        │ DOUBLE      │ YES     │ NULL    │ NULL    │ NULL    │
│ X883        │ DOUBLE      │ YES     │ NULL    │ NULL    │ NULL    │
│ X884        │ DOUBLE      │ YES     │ NULL    │ NULL    │ NULL    │
│ X885        │ DOUBLE      │ YES     │ NULL    │ NULL    │ NULL    │
│ X886        │ DOUBLE      │ YES     │ NULL    │ NULL    │ NULL    │
│ X887        │ DOUBLE      │ YES     │ NULL    │ NULL    │ NULL    │
│ X888        │ DOUBLE      │ YES     │ NULL    │ NULL    │ NULL    │
│ X889        │ DOUBLE      │ YES     │ NULL    │ NULL    │ NULL    │
│ X890        │ DOUBLE      │ YES     │ NULL    │ NULL    │ NULL    │
│ label       │ DOUBLE      │ YES     │ NULL    │ NULL    │ NULL    │
├─────────────┴─────────────┴─────────┴─────────┴─────────┴─────────┤
│ 896 rows (20 shown)                                     6 columns │
└───────────────────────────────────────────────────────────────────┘

だいたい900列ありますね。

またparquetファイルという普通にやったら編集できないファイル形式を使用しています。(csvファイルを容量削減し列方向の計算の高速化が行えるようなフォーマットにした...みたいなやつです。)

なんかさくっとデータ見たいなという時に容量が重すぎ&行列長すぎ&parquetファイルという感じなので普通の表計算ツールで読めません。(ExcelでもGoogleスプレッドシートでも)

今回このデータをそのまま読もうとしたのですが自分の環境ではきつそう(40分でアップロードできなかった)だったので一旦以下のコードで2万行・126MBくらいにしました。
ざっくりデータを横断できれば良いですし、この量のデータ全てを読み込む要件はないと思いますし...(そう願いたい。)

上位20000行取得してparquetファイルに保存するコード

2万行に削ります。

import duckdb

con = duckdb.connect(database=":memory:")
con.sql(f"COPY (SELECT * FROM '/Users/nk/Downloads/test (1).parquet' LIMIT 20000) TO 'output.parquet' (FORMAT PARQUET)")

ではrow zeroで試してみましょう。

以下のボタンをおすと...

モーダルでファイルをアップロードできるドロップエリアが表示されます。

ここにファイルをドラッグ&ドロップするだけです。


大体一分くらいで読めました!スクロールもまるで抵抗がないですね...!

Snowflake上のデータを読み込むために

次はSnowflakeSummitで紹介されていた(らしい)Snowflakeへの接続も試してみましょう。

とりあえず接続に必要そうな情報は
Account identifier(アカウント識別子)

Username(ユーザー名)

Password(パスワード)
みたいです。

この項目はSnowflake上で以下をクリックすると確認できました。(パスワード以外)

次にrowzero上でテスト接続すると接続が確認できたのですが以下の情報がいることがわかりました。

warehouse
role

要はデータがある場所(ウェアハウス)とそこにアクセスできるロールの設定が必要であるということです。
なのでSnowflake上で作りましょう。

Snowflakeにデータウェアハウスを作成してデータを読み込む。

せっかくなのでロール作成からやってみます。

CREATE ROLE data_analyst_role COMMENT = 'Role for analytics team members';

CREATE WAREHOUSE analytics_wh
  WITH WAREHOUSE_SIZE = 'SMALL'
  AUTO_SUSPEND = 300
  AUTO_RESUME = TRUE
  COMMENT = 'Warehouse for analytics workloads';

各パラメータの詳細
  1. WAREHOUSE_SIZE = 'SMALL'
    計算リソースのサイズを指定

利用可能なサイズ: X-SMALL, SMALL, MEDIUM, LARGE, X-LARGE, 2X-LARGE, 3X-LARGE, 4X-LARGE
SMALL: 8つのサーバーでクラスター構成
コスト: サイズが大きいほど高額、処理速度は向上
用途: 軽〜中程度の分析ワークロード

  1. AUTO_SUSPEND = 300
    自動停止時間(秒単位)

300秒 = 5分: 5分間アクティビティがないと自動停止
コスト削減: 停止中は課金されない
推奨値: 300-600秒(5-10分)
設定範囲: 60秒以上

  1. AUTO_RESUME = TRUE
    自動再開設定

TRUE: クエリ実行時に自動で再開
FALSE: 手動で再開が必要
通常はTRUE推奨: シームレスな利用が可能

  1. COMMENT = 'Warehouse for analytics workloads'
    説明文

用途説明: ウェアハウスの目的を記述
管理上重要: 複数ウェアハウス運用時の識別

ロールをユーザーに付与

GRANT ROLE data_analyst_role TO USER NK;
GRANT USAGE ON WAREHOUSE analytics_wh TO ROLE data_analyst_role;

データベースとスキーマ作成

CREATE DATABASE my_analytics_db;
CREATE SCHEMA my_analytics_db.data_schema;

GRANT USAGE ON DATABASE my_analytics_db TO ROLE data_analyst_role;
GRANT USAGE ON SCHEMA my_analytics_db.data_schema TO ROLE data_analyst_role;
GRANT CREATE TABLE ON SCHEMA my_analytics_db.data_schema TO ROLE data_analyst_role;
GRANT CREATE STAGE ON SCHEMA my_analytics_db.data_schema TO ROLE data_analyst_role;

作成したウェアハウス〜スキーマの使用を宣言します。

USE ROLE data_analyst_role;
USE WAREHOUSE analytics_wh;
USE DATABASE my_analytics_db;
USE SCHEMA data_schema;

parquet用のステージを作成します。

CREATE STAGE parquet_stage
  FILE_FORMAT = (TYPE = 'PARQUET');

このあと一旦UIからデータ(先ほどのparquetファイル)をアップロードします。
以下の画像の赤枠のところを押すとアップロード用のドロップダウンエリアが表示されるのでファイルをアップロードします。

テーブル作成

CREATE FILE FORMAT parquet_format
  TYPE = 'PARQUET'
  BINARY_AS_TEXT = FALSE;
CREATE TABLE my_data AS 
SELECT * FROM @parquet_stage
(FILE_FORMAT => 'parquet_format');

これでテーブルが作成されました。

row zero上で接続しましょう。

接続作成後にSnowflakeConnectionを選択すると...

右に何か出てきましたね。この画面上でSnowflake上のデータに接続できます。

先ほど作成したデータベース、スキーマを指定してSELECTすると

データが出てきました!
ただし自分のSnowflake上でのparquetファイルの読み込み方が悪かったのか一列にjson形式で読み込まれてしまっています。

以下Snowflake上でjsonをパースしたテーブルを作成しました。

CREATE OR REPLACE TABLE my_data_clean AS
SELECT 
    ROW_NUMBER() OVER (ORDER BY 1) AS row_id,
    PARSE_JSON($1):X1::FLOAT AS X1,
    PARSE_JSON($1):X10::FLOAT AS X10,
    PARSE_JSON($1):X100::FLOAT AS X100,
    PARSE_JSON($1):X101::FLOAT AS X101,
    PARSE_JSON($1):X102::FLOAT AS X102,
    PARSE_JSON($1):X103::FLOAT AS X103,
    PARSE_JSON($1):X104::FLOAT AS X104,
    PARSE_JSON($1):X105::FLOAT AS X105,
    PARSE_JSON($1):X106::FLOAT AS X106,
    PARSE_JSON($1):X107::FLOAT AS X107
FROM my_data;

今度はちゃんと表っぽく出ましたね。

row zeroも結構面白そうな製品なので今後に期待したいと思います!
今後の自分の課題としてはsnowflake上での自分のparquetファイルの扱い方をもう少し勉強したいです。

Discussion