Como configurar um Jupyter Notebook para o Snowpark Scala¶
Este tópico explica como configurar um Jupyter Notebook para o Snowpark.
Neste tópico:
Como configurar Jupyter Notebooks para o desenvolvimento em Scala¶
Certifique-se de que Jupyter esteja configurado para usar o Scala. Por exemplo, você pode instalar o kernel Almond.
Nota
Ao usar coursier
para instalar o kernel Almond, especifique uma versão do Scala suportada.
Como criar um novo Notebook em uma nova pasta¶
A biblioteca do Snowpark requer acesso ao diretório que contém as classes geradas pelo REPL do Scala. Se você está planejando usar vários notebooks, você deve usar um diretório de classes REPL separado para cada notebook.
Para facilitar a criação de um diretório de classes REPL separado para cada notebook, crie uma pasta separada para cada notebook:
No painel do Notebook, clique em New » Folder para criar uma nova pasta para um notebook.
Selecione a caixa de seleção ao lado da pasta, clique em Rename e atribua um novo nome para a pasta.
Clique no link da pasta para navegar para a pasta.
Clique em New » Scala para criar um novo notebook nessa pasta.
Como configurar o Jupyter Notebook para o Snowpark¶
Em seguida, configure o Jupyter Notebook para o Snowpark.
Em uma nova célula, execute os seguintes comandos para definir uma variável para um diretório:
val replClassPathObj = os.Path("replClasses", os.pwd) if (!os.exists(replClassPathObj)) os.makeDir(replClassPathObj) val replClassPath = replClassPathObj.toString()
Isso faz o seguinte:
Define uma variável os.Path e uma variável
String
para um diretório para classes geradas pelo REPL do Scala.Cria esse diretório se ele ainda não existir.
O REPL do Scala gera classes para o código Scala que você escreve, incluindo seu código que define UDFs. A biblioteca do Snowpark usa esse diretório para encontrar e carregar as classes para suas UDFs que são geradas pelo REPL.
Nota
Se você estiver usando vários notebooks, você precisará criar e configurar um diretório de classe REPL separado para cada notebook. Para simplificar, você pode simplesmente colocar cada notebook em uma pasta separada, como explicado em Como criar um novo Notebook em uma nova pasta.
Execute os seguintes comandos em uma célula para configurar o compilador para o REPL do Scala:
interp.configureCompiler(_.settings.outputDirs.setSingleOutput(replClassPath)) interp.configureCompiler(_.settings.Yreplclassbased) interp.load.cp(replClassPathObj)
Isso faz o seguinte:
Configura o compilador para gerar classes para o REPL no diretório que você criou anteriormente.
Configura o compilador para inserir o código inserido no REPL em classes, e não em objetos.
Adiciona o diretório que você criou anteriormente como uma dependência do interpretador do REPL.
Crie uma nova sessão no Snowpark e adicione o diretório de classes REPL que você criou anteriormente como uma dependência. Por exemplo:
// 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)
Consulte Como criar uma sessão para o Snowpark Scala para obter uma explicação das chaves
Map
.Execute os seguintes comandos em uma célula para adicionar as classes de kernel Ammonite como dependências para sua 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")
Nota
Se você planeja criar UDFs que tenham dependências disponíveis através do Maven, você pode usar o método
addClass
definido acima para adicionar essas dependências:addClass(session, "<dependency_package>.<dependency_class>")
Se você precisar especificar uma dependência em um arquivo JAR, chame
interp.load.cp
para carregar o arquivo JAR para o intérprete do REPL e chamesession.addDependency
para adicionar o arquivo JAR como uma dependência para suas UDFs:interp.load.cp(os.Path(<path to jar file>/<jar file>)) addDependency(<path to jar file>/<jar file>)
Como verificar a configuração de seu Notebook Jupyter¶
Execute os seguintes comandos em uma célula para verificar se você pode definir e chamar uma função anônima definida pelo usuário (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()
Solução de problemas¶
value res<n> is not a member of ammonite.$sess.cmd<n>.wrapper.Helper¶
Se ocorrer o seguinte erro:
value res<n> is not a member of ammonite.$sess.cmd<n>.wrapper.Helper
Exclua o conteúdo do diretório contendo as classes do REPL (o diretório com o caminho especificado pela variável replClassPath
) e reinicie o servidor do notebook.