Snowpark Scala用Jupyterノートブックの設定

このトピックでは、Snowpark用にJupyterノートブックを設定する方法について説明します。

このトピックの内容:

Scala開発用Jupyterノートブックの設定

JupyterでScalaを使用するように設定されていることを確認します。たとえば、 Almondカーネル をインストールできます。

注釈

coursier を使用してAlmondカーネルをインストールする場合は、 サポートされているバージョンのScala を指定します。

新しいフォルダー内での新しいノートブックの作成

Snowparkライブラリには、Scala REPL によって生成されたクラスを含むディレクトリへのアクセスが必要です。複数のノートブックを使用する場合は、ノートブックごとに個別の REPL クラスディレクトリを使用する必要があります。

ノートブックごとに個別の REPL クラスディレクトリの設定を簡単にするには、ノートブックごとに個別のフォルダーを作成します。

  1. ノートブックダッシュボード で、 New » Folder をクリックしてノートブック用の新しいフォルダーを作成します。

  2. フォルダーの横にあるチェックボックスを選択し、 Rename をクリックして、フォルダーに新しい名前を割り当てます。

  3. フォルダーのリンクをクリックして、フォルダーに移動します。

  4. New » Scala をクリックして、そのフォルダーに新しいノートブックを作成します。

Snowpark用Jupyterノートブックの構成

次に、Snowpark用Jupyterノートブックを構成します。

  1. 新しいセルで次のコマンドを実行して、ディレクトリの変数を定義します。

    val replClassPathObj = os.Path("replClasses", os.pwd)
    if (!os.exists(replClassPathObj)) os.makeDir(replClassPathObj)
    val replClassPath = replClassPathObj.toString()
    
    Copy

    これにより、次が実行されます。

    • Scala REPL によって生成されたクラスのディレクトリの os.Path 変数と String 変数を定義します。

    • そのディレクトリがまだ存在しない場合は、ディレクトリを作成します。

    Scala REPL は、 UDFs を定義するコードを含め、作成するScalaコードのクラスを生成します。Snowparkライブラリは、このディレクトリを使用して、 REPL によって生成された UDFs のクラスを検索してアップロードします。

    注釈

    複数のノートブックを使用している場合は、ノートブックごとに個別の REPL クラスディレクトリを作成して構成する必要があります。簡単にするために、 新しいフォルダー内での新しいノートブックの作成 で説明されているように、各ノートブックを別々のフォルダーに置くことができます。

  2. セルで次のコマンドを実行して、Scala REPL 用のコンパイラを構成します。

    interp.configureCompiler(_.settings.outputDirs.setSingleOutput(replClassPath))
    interp.configureCompiler(_.settings.Yreplclassbased)
    interp.load.cp(replClassPathObj)
    
    Copy

    これにより、次が実行されます。

    • 以前に作成したディレクトリに REPL のクラスを生成するようにコンパイラを構成します。

    • REPL に入力されたコードをオブジェクトではなく、クラスにラップするようにコンパイラを構成します。

    • 以前に作成したディレクトリを REPL インタープリターの依存関係として追加します。

  3. Snowparkで新しいセッションを作成 し、以前に作成した REPL クラスディレクトリを依存関係として追加します。例:

    // Import the Snowpark library from Maven.
    import $ivy.`com.snowflake:snowpark:1.10.0`
    
    import com.snowflake.snowpark._
    import com.snowflake.snowpark.functions._
    
    val session = Session.builder.configs(Map(
        "URL" -> "https://<account_identifier>.snowflakecomputing.com",
        "USER" -> "<username>",
        "PASSWORD" -> "<password>",
        "ROLE" -> "<role_name>",
        "WAREHOUSE" -> "<warehouse_name>",
        "DB" -> "<database_name>",
        "SCHEMA" -> "<schema_name>"
    )).create
    
    // Add the directory for REPL classes that you created earlier.
    session.addDependency(replClassPath)

    Map キーの説明については、 Snowpark Scalaのセッションの作成 をご参照ください。

  4. セルで次のコマンドを実行して、Ammoniteカーネルクラスを UDF の依存関係 として追加します。

    def addClass(session: Session, className: String): String = {
      var cls1 = Class.forName(className)
      val resourceName = "/" + cls1.getName().replace(".", "/") + ".class"
      val url = cls1.getResource(resourceName)
      val path = url.getPath().split(":").last.split("!").head
      session.addDependency(path)
      path
    }
    addClass(session, "ammonite.repl.ReplBridge$")
    addClass(session, "ammonite.interp.api.APIHolder")
    addClass(session, "pprint.TPrintColors")
    
    Copy

    注釈

    Mavenを介して利用できる依存関係を持つ UDFs を作成する場合は、上記で定義した addClass メソッドを使用して、これらの依存関係を追加できます。

    addClass(session, "<dependency_package>.<dependency_class>")
    
    Copy

    JAR ファイルに依存関係を指定する必要がある場合は、 interp.load.cp を呼び出して REPL インタープリターの JAR ファイルをロードし、 session.addDependency を呼び出して JAR ファイルを UDFs の依存関係として追加します。

    interp.load.cp(os.Path(<path to jar file>/<jar file>))
    addDependency(<path to jar file>/<jar file>)
    
    Copy

Jupyterノートブックの構成の確認

セルで次のコマンドを実行して、匿名のユーザー定義関数(UDF)を定義して呼び出すことができることを確認します。

class UDFCode extends Serializable {
  val appendLastNameFunc = (s: String) => {
    s"$s Johnson"
  }
}
// Define an anonymous UDF.
val appendLastNameUdf = udf((new UDFCode).appendLastNameFunc)
// Create a DataFrame that has a column NAME with a single row with the value "Raymond".
val df = session.sql("select 'Raymond' NAME")
// Call the UDF, passing in the values in the NAME column.
// Return a new DataFrame that has an additional column "Full Name" that contains the value returned by the UDF.
df.withColumn("Full Name", appendLastNameUdf(col("NAME"))).show()
Copy

トラブルシューティング

値res<n>はammonite.$sess.cmd<n>.wrapper.Helperのメンバーではありません。

次のエラーが発生した場合は、

value res<n> is not a member of ammonite.$sess.cmd<n>.wrapper.Helper
Copy

REPL クラスを含むディレクトリ(replClassPath 変数で指定されたパスを持つディレクトリ)の内容を削除し、ノートブックサーバーを再起動します。