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은 UDF를 정의하는 코드 등 작성하는 Scala 코드의 클래스를 생성합니다. Snowpark 라이브러리는 REPL이 생성한 UDF의 클래스를 찾고 업로드하는 데 이 디렉터리를 사용합니다.

    참고

    여러 노트북을 사용하는 경우, 각 노트북에 대해 별도의 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.9.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을 통해 사용 가능한 종속성이 있는 UDF를 만들려는 경우, 위에서 정의한 addClass 메서드를 사용하여 이러한 종속성을 추가할 수 있습니다.

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

    JAR 파일에 종속성을 지정해야 하는 경우, interp.load.cp 를 호출하여 REPL 인터프리터의 JAR 파일을 로딩하고 session.addDependency 를 호출하여 JAR 파일을 UDF의 종속성으로 추가하십시오.

    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

문제 해결

value 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 변수에 의해 지정된 경로가 있는 디렉터리)의 내용을 삭제하고 노트북 서버를 다시 시작하십시오.