Snowpark Migration Accelerator:ノートブック変換¶
コードベースのレポートノートブックに移動してみましょう:基本レポートノートブック-SqlServer Spark.ipynbパイプラインスクリプトと同じようなステップを踏んでいきます。
すべての問題の解決:ここでの「問題」とは、SMAによって発生した問題を意味します。出力コードを見てみましょう。解析エラーや変換エラーを解決し、警告を調査します。
セッションコールの解決:セッションコールをどのように出力コードに書くかは、ファイルを実行する場所によって異なります。コードファイルを元々実行しようとしていたのと同じ場所で実行し、その後Snowflakeで実行することで、この問題を解決します。
入出力の解決:異なるソースへの接続は、SMAで完全に解決することはできません。プラットフォームには違いがあり、SMAは通常それらを無視します。これは、ファイルを実行する場所にも影響されます。
クリーンアップとテスト:コードを実行してみます。うまくいくかどうか見てみましょう。このラボではスモークテストを行いますが、Snowpark Python Checkpointsなど、より広範なテストやデータ検証を行うツールもあります。
はじめましょう。
すべての問題の解決¶
では、ノートブックに書かれている問題を見てみましょう。
(ノートブックはVS Codeで開くことができますが、適切に表示するには、VS Code用のJupyter拡張機能をインストールすることをお勧めします。あるいは、Jupyterで開くこともできますが、Snowflakeは、Snowflake拡張機能がインストールされた VS Codeを推奨しています)
パイプラインファイルの場合と同様に、比較機能を使用してこれら2つを並べて表示できますが、その場合、jsonに似た形式になります。

このノートブックには、EWI が2つだけあるというわけではありません。検索バーに戻れば見つけることができるが、これはとても短いので、下にスクロールすることもできます。固有の問題は次のとおりです。
SPRKPY1002 => pyspark.sql.readwriter.DataFrameReader.jdbc is not supported.これはパイプラインファイルで発生した問題と似ていますが、それは書き込み呼び出しでした。これは、SQL サーバーデータベースへの読み取り呼び出しです。この問題については後ほど解決します。
SPRKPY1068 => "pyspark.sql.dataframe.DataFrame.toPandasは、ArrayType 型の列がある場合はサポートされませんが、回避策があります。詳細についてはドキュメントを参照してください。 これは別の警告です。Snowparkのこの関数に配列を渡すと、うまくいかないことがあります。テストするときは、この点に注目しましょう。
ノートブックと問題についてはこれで終わりです。解析エラーを解決し、入力/出力を修正する必要があることを認識しました。また、注意する必要がある潜在的な機能上の違いがいくつかあります。次のステップに進み、セッション呼び出しを解決しましょう。
セッション呼び出しの解決¶
レポートノートブックのセッション呼び出しを更新するには、セッション呼び出しのあるセルを見つける必要があります。セルは次のようになります。

では、パイプラインファイルですでにやったことをやってみましょう。
「spark」セッション変数へのすべての参照を「session」に変更します(ノートブック全体に適用されます)
スパークドライバーの構成機能を削除します。
前後は次のようになります。
# Old Session
spark = Session.builder.config('spark.driver.extraClassPath', driver_path).app_name("AdventureWorksSummary", True).getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":7,"minor":4,"patch":10},"attributes":{"language":"Python"}})
# New Session
# Session
session = Session.builder.app_name("AdventureWorksSummary", True).getOrCreate()
session.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":7,"minor":4,"patch":10},"attributes":{"language":"Python"}})
このセルには他のコードがあることに注意してください。このコード:
url = sql_server_url
properties = {'user' : sql_server_user, 'password' : sql_server_password}
# Spark dataframe.
#EWI: SPRKPY1002 => pyspark.sql.readwriter.DataFrameReader.jdbc is not supported
df = session.read.jdbc(url = url, table = 'dbo.DimCustomer', properties = properties)
print('Session successfully setup.')
読み取りステートメントを実行する準備はほぼ整いましたが、まだそこまでには至っていません。これをすべて別のセルに移動しましょう。このセルの下に新しいセルを作成し、このコードをそのセルに移動します。このようになります。

セッション呼び出しに必要なのはこれだけですか?いいえ。前のページの[セッション呼び出しに関する注意事項](pipeline-conversion.md#notes-on-the-session-calls)を思い出して(場合によっては見直して)ください。connection.tomlファイルに接続情報が含まれていることを確認するか、セッションで使用する接続パラメーターを明示的に指定する必要があります。
入出力の解決¶
では、入出力を解決しましょう。これは、ファイルをローカルで実行するか、Snowflakeで実行するかによって異なることに注意してください。ただし、ノートブックに関しては、すべてをローカルでもSnowflakeでも実行できます。セッションを呼び出す必要もないので、コードは少しシンプルになります。アクティブなセッションを取得するだけです。パイプラインファイルと同様に、ローカルで実行/オーケストレーションする部分と、Snowflakeで実行する部分の2つに分けて行います。
レポーティングノートブックでの入出力の作業は、パイプラインのときよりもかなり簡単になります。ここでは、ローカルファイルからの読み込みやファイル間のデータ移動は行われません。単純に、SQL サーバーのテーブルからの読み取りが、Snowflakeのテーブルから読み取られるようになりました。SQL サーバーにはアクセスしないので、SQL サーバープロパティへの参照をすべて削除できます。また、読み取りステートメントはSnowflakeのテーブルステートメントに置き換えることができます。このセルの前後は次のようになります。
# Before
url = sql_server_url
properties = {'user' : sql_server_user, 'password' : sql_server_password}
# Spark dataframe.
#EWI: SPRKPY1002 => pyspark.sql.readwriter.DataFrameReader.jdbc is not supported
df = session.read.jdbc(url = url, table = 'dbo.DimCustomer', properties = properties)
print('Session successfully setup.')
# After
# New table call
# Snowpark Dataframe table.
df = session.table('ADVENTUREWORKS.DBO.DIMCUSTOMER')
print('Table loaded successfully.')
df.show()

以上です。ノートブックファイルのクリーンアップとテストに移りましょう。
クリーンアップとテスト¶
前回パイプラインファイルで行ったようにクリーンアップを実行してみましょう。インポートコールをまったく見ておらず、まったく必要のない構成ファイルもあります。まず、構成ファイルへの参照を削除することから始めましょう。これは、インポートステートメントとセッション呼び出しの間にある各セルになります。

では、インポートを見てみましょう。osへの参照は削除できます。(元のファイルでも使用されていないようですが...)pandasへの参照があります。構成ファイルが参照されるようになったため、このノートブックではpandasが使用されていないようです。レポートセクションのSnowpark dataframe API の一部としてtoPandas参照がありますが、これはpandasライブラリの一部ではありません。
オプションで、pandasへのインポート呼び出しをすべてmodinのpandasライブラリに置き換えることができます。このライブラリは、Snowflakeの強力なコンピューティングを活用するためにpandasのデータフレームを最適化します。この変更は次のようになります。
# Old
import pandas as pd
# New
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
そうは言っても、これも削除できます。SMA によって、Spark特有のインポートステートメントがすべてSnowparkに関連するものに置き換えられていることに注意してください。最終的なインポートセルは次のようになります。

これでクリーンアップは完了です。レポートと視覚化セルにはまだいくつかの EWIs が残っていますが、作成できそうです。これを実行し、出力が得られるか見てみましょう。

やりました。レポートは、Sparkノートブックが出力したものと一致しているようです。レポートセルが複雑に見えても、Snowparkはそれに対応できます。SMA から問題があるかもしれないと知らされましたが、問題はないようです。より多くのテストが必要ですが、最初のスモークテストは合格しました。
では、このノートブックをSnowsightで見てみよう。パイプラインファイルとは異なり、これはすべてSnowsightで行うことができます。
Snowsightでノートブックを実行する¶
今あるノートブックのバージョン(問題、セッション呼び出し、入出力を処理したもの)をSnowflakeに読み込んでみましょう。これを行うには、SnowSight のノートブックセクションにアクセスします。

そして、右上の「+ノートブック」ボタンの隣にある下向き矢印を選択し、「Import .ipynb file」(上記参照)を選択します。
これがインポートされたら、プロジェクトフォルダー内の SMA で作成された出力ディレクトリで作業していたノートブックファイルを選択します。
ノートブックの作成ダイアログウィンドウが開きます。今回のアップロードでは、以下のオプションを選択します。
ノートブックの場所:
データベース: ADVENTUREWORKS
スキーマ: DBO
Python環境: ウェアハウスで実行
これは、mlがたくさんある大きなノートブックではありません。これは基本的なレポートノートです。ウェアハウスでこれを実行することができます。
クエリウェアハウス: DEFAULT_WH
ノートブックウェアハウス: DEFAULT ˶_WH(システムで選択されたウェアハウスのままでもかまいません(streamlit倉庫になります)...このノートでは問題ありません)
これらのセレクションは下記で見ることができます。

これでノートブックがSnowflakeに読み込まれ、次のように表示されます。

ノートブックがSnowsightで実行されることを確認するために、ローカルでテストしたバージョンからいくつかの簡単なチェックや変更を行う必要があります。
アクティブなセッションを取得するためにセッション呼び出しを変更します
インストールが必要な依存ライブラリが利用可能であることを確認します
1つ目から始めましょう。最初に多くの時間を費やした後にセッション呼び出しを再度変更するのは奇妙に思えるかもしれませんが、現在はSnowflake内で実行されています。セッション呼び出しの読み取りに関連するものをすべて削除し、ほとんどのSnowflakeノートブックの先頭に標準的にある 「get_active_session」呼び出しに置き換えることができます。
//# Old for Jupyter
session = Session.builder.app_name("AdventureWorksSummary", True).getOrCreate()
# New for Snowsight
from snowflake.snowpark.context import get_active_session
session = get_active_session()
すでに接続されているので、接続パラメーターを指定したり、.tomlファイルを更新したりする必要はありません。今Snowflake内にいます。
セル内の古いコードを新しいコードに置き換えてみましょう。次のようになります。

ここで、今回の実行で利用可能なパッケージについて説明しましょう。何を追加する必要があるかを考える必要はありません。Snowflakeに任せましょう。ノートブックを使う良い点のひとつは、個々のセルを動かして結果を確認できることです。インポートライブラリのセルを動かしてみましょう。
まだの方は、画面右上の 「開始」と書いてあるところをクリックしてセッションを開始してください。

ノートブックの一番上のセルを実行すると、matplotlibがセッションにロードされていないことに気づくはずです。

これはこのノートブックにとってかなり重要なことです。ノートブックの右上にある「パッケージ」オプションを使って、そのライブラリをノートブック/セッションに追加することができます。

matplotlib を検索して選択します。これで、このパッケージはセッションで使用可能になります。

このライブラリをロードしたら、セッションを再開する必要があります。セッションを再開したら、最初のセルをもう一度実行してください。今回は成功したと言われるでしょう。

パッケージがロードされ、セッションが修正され、コード内の残りの問題がすでに解決されているので、ノートブックの残りの部分をチェックするにはどうすればよいでしょうか。では実行してみましょう。画面右上の「Run all」を選択して、ノートブックのすべてのセルを実行し、エラーが出るか確認してみましょう。
どうやら成功したようです。

2つのノートブックの実行を比較すると、Snowflakeバージョンではすべての出力データセットが最初に置かれ、その後に画像が続くのに対し、Spark Jupyter Notebookではそれらが混在しているという点だけが異なるように見えます。

この違いは、API の違いではなく、Snowflakeのノートブックがこれをどのようにオーケストレーションするかの違いであることに注意してください。これはおそらく、AdventureWorks が受け入れる違いでしょう。
結論¶
SMA を活用することで、データパイプラインとレポーティングノートブックの両方の移行を加速させることができました。それぞれが多ければ多いほど、SMA のようなツールが提供できる価値は高くなります。
これまで一貫して行ってきた評価 -> 変換 -> 検証のフローに戻りましょう。この移行では、次を行いました。
SMA でプロジェクトをセットアップした
SMA の評価および変換エンジンをコードファイルに対して実行した
SMA からの出力レポートを精査し、何を得たかをよりよく理解した
SMA で変換できなかったものを VS Codeで精査する
問題やエラーを解決する
セッション参照を解決する
入出力参照を解決する
ローカルでコードを実行する
Snowflakeでコードを実行する
新しく移行したスクリプトを実行し、その成功を検証した
Snowflakeは、 SnowConvert 、 SnowConvert 移行アシスタント、Snowpark Migration Acceleratorのような移行ツールの改善に時間を費やしてきたのと同様に、インジェストとデータエンジニアリング機能の改善に多大な時間を費やしてきました。これらはそれぞれ今後も改善され続けるでしょう。移行ツールについてご提案がありましたら、お気軽にご連絡ください。これらのチームは、ツールを改善するための追加のフィードバックを常に求めています。