Einrichten eines Jupyter-Notebooks für Snowpark

Unter diesem Thema wird erklärt, wie Sie ein Jupyter-Notebook für Snowpark einrichten.

Unter diesem Thema:

Einrichten eines Jupyter-Notebooks zur Scala-Entwicklung

Stellen Sie sicher, dass Jupyter für die Verwendung von Scala eingerichtet ist. Sie können zum Beispiel den Almond-Kernel installieren.

Bemerkung

Wenn Sie coursier verwenden, um den Almond-Kernel zu installieren, geben Sie eine unterstützte Version von Scala an.

Konfigurieren des Jupyter-Notebooks für Snowpark

Als Nächstes konfigurieren Sie das Jupyter-Notebook für Snowpark.

  1. Führen Sie in einer neuen Zelle die folgenden Befehle aus, um das Notebook für die Verwendung eines Maven-Repositorys für eine Bibliothek zu konfigurieren, von der Snowpark abhängt:

    import sys.process._
    val osgeoRepo = coursierapi.MavenRepository.of("https://repo.osgeo.org/repository/release")
    interp.repositories() ++= Seq(osgeoRepo)
    

    Bemerkung

    Diese Befehle müssen von einer anderen Zelle aus ausgeführt werden als die übrigen Befehle in diesem Abschnitt.

  2. Führen Sie in einer neuen Zelle die folgenden Befehle aus, um eine Variable für ein Verzeichnis zu definieren:

    import sys.process._
    val replClassPath = "<path_to_a_new_directory>" // e.g. /home/myusername/replClasses
    s"mkdir -p $replClassPath" !
    

    Dies bewirkt Folgendes:

    • Definiert eine Variable für ein Verzeichnis für Klassen, die von der Scala REPL generiert werden.

    • Erstellt dieses Verzeichnis.

    Bemerkung

    Stellen Sie sicher, dass Sie über die Berechtigungen des Betriebssystems verfügen, um ein Verzeichnis an diesem Speicherort zu erstellen.

    Die Scala REPL generiert Klassen für den von Ihnen geschriebenen Scala-Code, einschließlich des Codes, der die UDFs definiert. Die Snowpark-Bibliothek verwendet dieses Verzeichnis, um die von der REPL für Ihre UDFs generierten Klassen zu finden und hochzuladen.

    Bemerkung

    Wenn Sie mehrere Notebooks verwenden, müssen Sie für jedes Notebook ein eigenes REPL-Klassenverzeichnis erstellen und konfigurieren.

  3. Führen Sie die folgenden Befehle in einer Zelle aus, um den Compiler für die Scala REPL zu konfigurieren:

    interp.configureCompiler(_.settings.outputDirs.setSingleOutput(replClassPath))
    interp.configureCompiler(_.settings.Yreplclassbased)
    interp.load.cp(os.Path(replClassPath))
    

    Dies bewirkt Folgendes:

    • Konfiguriert den Compiler so, dass er Klassen für die REPL in dem Verzeichnis generiert, das Sie zuvor erstellt haben.

    • Konfiguriert den Compiler so, dass Code, der in REPL eingegeben wird, in Klassen und nicht in Objekten gepackt wird.

    • Fügt das zuvor von Ihnen erstellte Verzeichnis als Abhängigkeit des REPL-Interpreters hinzu.

  4. Erstellen Sie eine neue Sitzung in Snowpark, und fügen Sie das REPL-Klassenverzeichnis, das Sie zuvor erstellt haben, als Abhängigkeit hinzu. Beispiel:

    // Import the Snowpark library from Maven.
    import $ivy.`com.snowflake:snowpark:0.6.0`
    
    import com.snowflake.snowpark._
    import com.snowflake.snowpark.functions._
    
    val session = Session.builder.configs(Map(
        "URL" -> "https://<account_identifier>.snowflakecomputing.com",
        "USER" -> "<username>",
        "PRIVATEKEY" -> "<private rsa key copied from your private key file>",
        "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)

    Weitere Informationen zu den Map-Schlüsseln finden Sie unter Erstellen einer Sitzung für Snowpark.

  5. Führen Sie die folgenden Befehle in einer Zelle aus, um die Ammonite-Kernelklassen als Abhängigkeiten für Ihre UDF hinzuzufügen:

    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")
    

    Bemerkung

    Wenn Sie vorhaben, UDFs mit Abhängigkeiten zu erstellen, die über Maven verfügbar sind, können Sie diese Abhängigkeiten mit der oben definierten addClass-Methode hinzuzufügen:

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

    Wenn Sie eine Abhängigkeit in einer JAR-Datei angeben müssen, rufen Sie interp.load.cp auf, um die JAR-Datei für den REPL-Interpreter zu laden, und rufen Sie session.addDependency auf, um die JAR-Datei als Abhängigkeit für Ihre UDFs hinzuzufügen:

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

Überprüfen der Konfiguration Ihres Jupyter-Notebooks

Führen Sie die folgenden Befehle in einer Zelle aus, um sicherzustellen, dass Sie eine anonyme benutzerdefinierte Funktion (UDF) definieren und aufrufen können:

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()