Iskra é uma biblioteca wrapper Scala 3 em torno da API Apache Spark que permite escrever código Spark seguro e sem clichês, mas ainda assim eficiente.
A partir do lançamento do 3.2.0, o Spark é compilado cruzadamente também para o Scala 2.13, o que abre uma maneira de usar o Spark a partir do código do Scala 3, já que os projetos do Scala 3 podem depender dos artefatos do Scala 2.13.
No entanto, pode-se encontrar problemas ao tentar chamar um método que requer uma instância implícita do tipo Encoder
do Spark. A derivação de instâncias do Encoder
depende da presença de um TypeTag
para um determinado tipo. No entanto, TypeTag
s não são mais gerados pelo compilador Scala 3 (e não há planos para oferecer suporte a isso), portanto, instâncias de Encoder
não podem ser sintetizadas automaticamente na maioria dos casos.
O Iskra tenta contornar esse problema usando seus próprios codificadores (não relacionados ao tipo Encoder
do Spark) gerados usando a nova API de metaprogramação do Scala 3.
O Iskra fornece wrappers finos (mas fortemente tipados) em torno de DataFrame
s, que rastreiam tipos e nomes de colunas em tempo de compilação, mas permitem que o Catalyst execute todas as suas otimizações em tempo de execução.
O Iskra usa tipos estruturais em vez de classes de caso como modelos de dados, o que nos dá muita flexibilidade (não há necessidade de definir explicitamente uma nova classe de caso quando uma coluna é adicionada/removida/renomeada!), mas ainda obtemos erros de compilação quando tentamos referem-se a uma coluna que não existe ou não pode ser usada em um determinado contexto.
//> using lib " org.virtuslab::iskra:0.0.3 "
scala-cli repl --dep org.virtuslab::iskra:0.0.3
build.sbt
em um projeto sbt: libraryDependencies + = " org.virtuslab " %% " iskra " % " 0.0.3 "
O Iskra é construído com Scala 3.1.3, portanto é compatível com Scala 3.1.x e versões secundárias mais recentes (a partir de 3.2.0 você obterá preenchimentos de código para nomes de colunas em REPL e Metals!). O Iskra depende transitivamente do Spark 3.2.0.
import org . virtuslab . iskra . api . *
given spark : SparkSession =
SparkSession
.builder()
.master( " local " )
.appName( " my-spark-app " )
.getOrCreate()
toTypedDF
em uma Seq
de classes de caso, por exemplo Seq ( Foo ( 1 , " abc " ), Foo ( 2 , " xyz " )).toTypedDF
typed
nele com um parâmetro de tipo representando uma classe de caso, por exemplo df.typed[ Foo ]
Caso você precise voltar ao mundo inseguro dos quadros de dados não digitados por algum motivo, basta chamar .untyped
em um quadro de dados digitado.
Esta biblioteca pretende se assemelhar ao máximo à API original do Spark (por exemplo, usando os mesmos nomes de métodos, etc.) sempre que possível, embora tente fazer o código parecer mais com Scala normal, sem clichês desnecessários e adicionando algumas outras melhorias sintáticas.
Diferenças mais importantes:
$.foo.bar
em vez de $"foo.bar"
ou col("foo.bar")
. Use crases quando necessário, por exemplo $.`column with spaces`
..select(...)
ou .select{...}
você deve retornar algo que seja uma coluna nomeada ou uma tupla de colunas nomeadas. Por causa de como a sintaxe Scala funciona, você pode escrever simplesmente .select($.x, $.y)
em vez de select(($.x, $.y))
. Com chaves você pode calcular valores intermediários como .select {
val sum = ($.x + $.y).as( " sum " )
($.x, $.y, sum)
}
foos.innerJoin(bars).on($.foos.barId === $.bars.id).select(...)
foos
e bars
foram inferidos automaticamente Este projeto é construído usando scala-cli, então basta usar os comandos tradicionais com .
como root como scala-cli compile .
ou scala-cli test .
.
Para uma versão mais recente da seção Usage
, veja aqui