この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
本エントリは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
Snowflake SQLAlchemy
Snowflake SQLAlchemy を基に実装します。
snowflake-sqlalchemy
と sqlalchemy
パッケージを使います。
↓コードはこんな感じです。
クリックでコードを表示する/折りたたむ
- 出力(
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:SnowflakeのALTER TABLE SWAPが超絶的に便利だった件」 の予定です。
参考文献
SQLAlchemy関連です。