#12:Connector for PythonでPandasにデータを読み込む – Snowflake Advent Calendar 2019 #SnowflakeDB

Snowflake Connector for Python を使用して Pandas に読み込む方法と、 Snowflake SQLAlchemy を使用して読み込む方法のそれぞれを紹介
2019.12.12

本エントリはSnowflake Advent Calender 2019のエントリです。

データアナリティクス事業本部、池田です。
なんかいろいろありまして勢いでアドベントカレンダーに参加しております。
なんとなくAPI系がよかったので題材を探していたところ、 Python からSnowflakeへ接続する方法がありましたので紹介します。
SnowflakeのエディションはENTERPRISEです。

今回使用するデータ

まずはWebのコンソールから接続してみます。
今回はトライアル版にもある天気のテーブル SNOWFLAKE_SAMPLE_DATA.WEATHER.WEATHER_14_TOTAL を使用しました。 WEATHERスキーマには複数テーブルがありますが、WEATHER_14_TOTALが実績でそれ以外が予報のようです。 ( サンプルの説明
また、データがJSONで格納されており、(心が折れかけましたが、) ハンズオンラボガイドに扱い方があるようで、弊社でも既に ブログ なっていました。
ちなみにこのテーブルのデータは約1時間おきにレコードが追加されるようです。

特定の都市の特定の月の気温と天気の説明を参照する、こんな感じのクエリを書いてみました。

SELECT
    v:city:name::string AS display_city,
    -- date_trunc('month', '2019-11-01'::date) AS display_month,
    DATE_TRUNC('month', CURRENT_DATE()) AS display_month,
    TO_TIMESTAMP_LTZ(v:time) AS datetime,
    v:main:temp - 273.15 AS temp,
    v:weather[0]:description::string AS desc
FROM
    WEATHER_14_TOTAL
WHERE
    v:city:country = 'JP'
AND v:city:name = 'Tokyo'
AND datetime >= display_month
AND datetime < DATEADD('month', 1, display_month)
ORDER BY
    v:time
;

↓結果こんな感じです。

組み込みの関数は リファレンスの一覧 で探しながら書きました。 また、結果ビューに表示される日時のタイムゾーンが太平洋だったので、 東京にするために、 この辺 を参考にタイムゾーンの設定を変えています。

このテーブルの情報をPythonでプロットする辺りまでをやってみます。

Snowflake Connector for Python

ガイド を基にPythonパッケージのインストールなど 環境を準備します。 snowflake-connector-python パッケージが必要になります。 (私はAnaconda使っているので、condaでパッケージが見つからない時は conda install -c conda-forge snowflake-connector-python みたいな感じで 別チャンネルから取得する必要がありました。)

Python Connector API に従いながらコードを作成します。
↓結果がこんな感じです。

クリックでコードを表示する/折りたたむ
  • 出力( print(*data, sep="\n") の一部)
('Tokyo', datetime.date(2019, 12, 1), datetime.datetime(2019, 12, 1, 0, 1, 54, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>), 4.19, 'few clouds')
('Tokyo', datetime.date(2019, 12, 1), datetime.datetime(2019, 12, 1, 1, 1, 55, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>), 3.7, 'few clouds')
('Tokyo', datetime.date(2019, 12, 1), datetime.datetime(2019, 12, 1, 2, 1, 56, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>), 4.49, 'broken clouds')
('Tokyo', datetime.date(2019, 12, 1), datetime.datetime(2019, 12, 1, 3, 2, 45, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>), 4.55, 'broken clouds')
('Tokyo', datetime.date(2019, 12, 1), datetime.datetime(2019, 12, 1, 4, 2, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>), 4.46, 'broken clouds')
…
  • 出力( df.info()
    カラム名が大文字になっていますね。
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 229 entries, 0 to 228
Data columns (total 5 columns):
DISPLAY_CITY     229 non-null object
DISPLAY_MONTH    229 non-null object
DATETIME         229 non-null datetime64[ns, UTC]
TEMP             229 non-null float64
DESC             229 non-null object
dtypes: datetime64[ns, UTC](1), float64(1), object(3)
memory usage: 9.1+ KB
  • 出力( df.plot()

    東京寒いですね。

Snowflake SQLAlchemy

Snowflake SQLAlchemy を基に実装します。 snowflake-sqlalchemysqlalchemy パッケージを使います。

↓コードはこんな感じです。

クリックでコードを表示する/折りたたむ
  • 出力( df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 230 entries, 0 to 229
Data columns (total 5 columns):
display_city     230 non-null object
display_month    230 non-null object
datetime         230 non-null datetime64[ns, UTC]
temp             230 non-null float64
desc             230 non-null object
dtypes: datetime64[ns, UTC](1), float64(1), object(3)
memory usage: 9.1+ KB

こちらの方法で読み込んだ時はカラム名は小文字になりました。 先述のドキュメントによると Snowflake stores all case-insensitive object names in uppercase text. In contrast, SQLAlchemy considers all lowercase object names to be case-insensitive. らしいです。へー。

SQLAlchemyっぽい書き方をしてみる

せっかくなので、っぽい書き方で接続してみました。 (WEATHERスキーマのJSONのテーブルだと苦労しそうだったので、別のテーブルを使っています。)

↓コードはこんな感じです。

クリックでコードを表示する/折りたたむ
  • 出力( print(*my_items, sep='\n')
224558, AAAAAAAAOCNGDAAA, Dominant, implicit months ought to join. Alone p, Music
224559, AAAAAAAAOCNGDAAA, Structural times must consider often, Electronics

ORMっぽい。

おわりに

チュートリアルなど一切やれていないまま勢いでとりあえず触ってみましたが、 (英語ですが)ドキュメントも充実していてやりたいことはできました。 あとはクエリのレスポンスが早くて、すごいなー、へー、と思いました。 でも今回一番驚いたのは、東京の気温の低さです。こんなに寒くなっていたとは思ってませんでした…

で、明日13日の金曜日甲木 洋介 がもたらす 恐怖戦慄の「#13:SnowflakeALTER TABLE SWAPが超絶的に便利だった件」 の予定です。

参考文献

SQLAlchemy関連です。