Snowpark Migration Accelerator: Códigos de problema para Python¶
SPRKPY1089¶
Mensagem: Os valores de pyspark.sql.readwriter.DataFrameWriter.options no Snowpark podem ser diferentes, portanto, pode ser necessária uma validação.
Categoria: Aviso
Descrição¶
Os valores de pyspark.sql.readwriter.DataFrameWriter.options no Snowpark podem ser diferentes, portanto, pode ser necessária uma validação para garantir que o comportamento esteja correto.
Cenários¶
Há alguns cenários, dependendo do fato de as opções terem suporte ou não, ou do formato usado para gravar o arquivo.
Cenário 1¶
Entrada
Veja a seguir um exemplo de uso das opções de método, adicionando as opções sep
e nullValue
, que atualmente são suportadas
.
df = spark.createDataFrame([(1, "myVal")], [2, "myVal2"], [None, "myVal3" ])
df.write.options(nullValue="myVal", sep=",").csv("some_path")
Saída
A ferramenta adiciona EWI SPRKPY1089
indicando que se trata de uma validação obrigatória.
df = spark.createDataFrame([(1, "myVal")], [2, "myVal2"], [None, "myVal3" ])
#EWI: SPRKPY1089 => The pyspark.sql.readwriter.DataFrameWriter.options values in Snowpark may be different, so required validation might be needed.
df.write.options(nullValue="myVal", sep=",").csv("some_path")
Correção recomendada
O Snowpark API é compatível com esses parâmetros, portanto, a única ação a ser tomada é verificar o comportamento após a migração. Consulte a tabela Equivalências para ver os parâmetros compatíveis.
df = spark.createDataFrame([(1, "myVal")], [2, "myVal2"], [None, "myVal3" ])
#EWI: SPRKPY1089 => The pyspark.sql.readwriter.DataFrameWriter.options values in Snowpark may be different, so required validation might be needed.
df.write.options(nullValue="myVal", sep=",").csv("some_path")
Cenário 2¶
Entrada
Aqui o cenário mostra o uso de opções, mas adiciona uma opção de cabeçalho
, que não é suportada
.
df = spark.createDataFrame([(1, "myVal")], [2, "myVal2"], [None, "myVal3" ])
df.write.options(header=True, sep=",").csv("some_path")
Saída
A ferramenta adiciona o EWI SPRKPY1089
indicando que a validação é necessária.
df = spark.createDataFrame([(1, "myVal")], [2, "myVal2"], [None, "myVal3" ])
#EWI: SPRKPY1089 => The pyspark.sql.readwriter.DataFrameWriter.options values in Snowpark may be different, so required validation might be needed.
df.write.options(header=True, sep=",").csv("some_path")
Correção recomendada
Para esse cenário, é recomendável avaliar as opções de tipo de formato do Snowpark para ver se é possível alterá-lo de acordo com suas necessidades. Além disso, verifique o comportamento após a alteração.
df = spark.createDataFrame([(1, "myVal")], [2, "myVal2"], [None, "myVal3" ])
#EWI: SPRKPY1089 => The pyspark.sql.readwriter.DataFrameWriter.options values in Snowpark may be different, so required validation might be needed.
df.write.csv("some_path")
Cenário 3¶
Entrada
Esse cenário adiciona uma opção sep
, que é suportada
e usa o método JSON
.
df = spark.createDataFrame([(1, "myVal")], [2, "myVal2"], [None, "myVal3" ])
df.write.options(nullValue="myVal", sep=",").json("some_path")
Saída
A ferramenta adiciona o EWI SPRKPY1089
indicando que a validação é necessária.
Observação: esse cenário também se aplica a
PARQUET
.
df = spark.createDataFrame([(1, "myVal")], [2, "myVal2"], [None, "myVal3" ])
#EWI: SPRKPY1089 => The pyspark.sql.readwriter.DataFrameWriter.options values in Snowpark may be different, so required validation might be needed.
df.write.options(nullValue="myVal", sep=",").json("some_path")
Correção recomendada
O formato de arquivo JSON
não é compatível com o parâmetro sep
, portanto, é recomendável avaliar as opções de tipo de formato do Snowpark para ver se é possível alterá-lo de acordo com suas necessidades. Além disso, verifique o comportamento após a alteração.
df = spark.createDataFrame([(1, "myVal")], [2, "myVal2"], [None, "myVal3" ])
#EWI: SPRKPY1089 => The pyspark.sql.readwriter.DataFrameWriter.options values in Snowpark may be different, so required validation might be needed.
df.write.json("some_path")
Recomendações adicionais¶
Como existem alguns parâmetros
não suportados
, recomenda-se verificar atabela de equivalências
e verificar o comportamento após a transformação.Tabela de equivalências:
O Snowpark pode oferecer suporte a uma lista de equivalências para alguns parâmetros:
Opção PySpark |
Opção SnowFlake |
Formatos de arquivo suportados |
Descrição |
---|---|---|---|
SEP |
FIELD_DELIMITER |
CSV |
Um ou mais caracteres de byte único ou de vários bytes que separam os campos em um arquivo de entrada. |
LINESEP |
RECORD_DELIMITER |
CSV |
Um ou mais caracteres que separam registros em um arquivo de entrada. |
QUOTE |
FIELD_OPTIONALLY_ENCLOSED_BY |
CSV |
Caractere usado para delimitar as cadeias de caracteres. |
NULLVALUE |
NULL_IF |
CSV |
String usada para converter de e para SQL NULL. |
DATEFORMAT |
DATE_FORMAT |
CSV |
String que define o formato dos valores de data nos arquivos de dados a serem carregados. |
TIMESTAMPFORMAT |
TIMESTAMP_FORMAT |
CSV |
String que define o formato dos valores de carimbo de data/hora nos arquivos de dados a serem carregados. |
Se o parâmetro usado não estiver na lista, a API gera um erro.
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1088¶
Mensagem: Os valores de pyspark.sql.readwriter.DataFrameWriter.option no Snowpark podem ser diferentes, portanto, pode ser necessária uma validação.
Categoria: Aviso
Descrição¶
Os valores de pyspark.sql.readwriter.DataFrameWriter.option no Snowpark podem ser diferentes, portanto, pode ser necessária uma validação para garantir que o comportamento esteja correto.
Cenários¶
Há alguns cenários, dependendo da opção ser suportada ou não, ou do formato usado para gravar o arquivo.
Cenário 1¶
Entrada
Veja abaixo um exemplo de uso da opção de método, adicionando uma opção sep
, que atualmente é suportada
.
df = spark.createDataFrame([(100, "myVal")], ["ID", "Value"])
df.write.option("sep", ",").csv("some_path")
Saída
A ferramenta adiciona EWI SPRKPY1088
indicando que se trata de uma validação obrigatória.
df = spark.createDataFrame([(100, "myVal")], ["ID", "Value"])
#EWI: SPRKPY1088 => The pyspark.sql.readwriter.DataFrameWriter.option values in Snowpark may be different, so required validation might be needed.
df.write.option("sep", ",").csv("some_path")
Correção recomendada
O Snowpark API oferece suporte a esse parâmetro, portanto, a única ação pode ser verificar o comportamento após a migração. Consulte a tabela Equivalências para ver os parâmetros compatíveis.
df = spark.createDataFrame([(100, "myVal")], ["ID", "Value"])
#EWI: SPRKPY1088 => The pyspark.sql.readwriter.DataFrameWriter.option values in Snowpark may be different, so required validation might be needed.
df.write.option("sep", ",").csv("some_path")
Cenário 2¶
Entrada
Aqui o cenário mostra o uso da opção, mas adiciona uma opção de cabeçalho
, que é não suportada
.
df = spark.createDataFrame([(100, "myVal")], ["ID", "Value"])
df.write.option("header", True).csv("some_path")
Saída
A ferramenta adiciona o EWI SPRKPY1088
indicando que a validação é necessária.
df = spark.createDataFrame([(100, "myVal")], ["ID", "Value"])
#EWI: SPRKPY1088 => The pyspark.sql.readwriter.DataFrameWriter.option values in Snowpark may be different, so required validation might be needed.
df.write.option("header", True).csv("some_path")
Correção recomendada
Para esse cenário, é recomendável avaliar as opções de tipo de formato do Snowpark para ver se é possível alterá-lo de acordo com suas necessidades. Além disso, verifique o comportamento após a alteração.
df = spark.createDataFrame([(100, "myVal")], ["ID", "Value"])
#EWI: SPRKPY1088 => The pyspark.sql.readwriter.DataFrameWriter.option values in Snowpark may be different, so required validation might be needed.
df.write.csv("some_path")
Cenário 3¶
Entrada
Esse cenário adiciona uma opção sep
, que é suportada
e usa o método JSON
.
Observação: esse cenário também se aplica a
PARQUET
.
df = spark.createDataFrame([(100, "myVal")], ["ID", "Value"])
df.write.option("sep", ",").json("some_path")
Saída
A ferramenta adiciona o EWI SPRKPY1088
indicando que a validação é necessária.
df = spark.createDataFrame([(100, "myVal")], ["ID", "Value"])
#EWI: SPRKPY1088 => The pyspark.sql.readwriter.DataFrameWriter.option values in Snowpark may be different, so required validation might be needed.
df.write.option("sep", ",").json("some_path")
Correção recomendada
O formato de arquivo JSON
não é compatível com o parâmetro sep
, portanto, é recomendável avaliar as opções de tipo de formato do Snowpark para ver se é possível alterá-lo de acordo com suas necessidades. Além disso, verifique o comportamento após a alteração.
df = spark.createDataFrame([(100, "myVal")], ["ID", "Value"])
#EWI: SPRKPY1088 => The pyspark.sql.readwriter.DataFrameWriter.option values in Snowpark may be different, so required validation might be needed.
df.write.json("some_path")
Recomendações adicionais¶
Como existem alguns parâmetros
não suportados
, recomenda-se verificar atabela de equivalências
e verificar o comportamento após a transformação.Tabela de equivalências:
Opção PySpark |
Opção SnowFlake |
Formatos de arquivo suportados |
Descrição |
---|---|---|---|
SEP |
FIELD_DELIMITER |
CSV |
Um ou mais caracteres de byte único ou de vários bytes que separam os campos em um arquivo de entrada. |
LINESEP |
RECORD_DELIMITER |
CSV |
Um ou mais caracteres que separam registros em um arquivo de entrada. |
QUOTE |
FIELD_OPTIONALLY_ENCLOSED_BY |
CSV |
Caractere usado para delimitar as cadeias de caracteres. |
NULLVALUE |
NULL_IF |
CSV |
String usada para converter de e para SQL NULL. |
DATEFORMAT |
DATE_FORMAT |
CSV |
String que define o formato dos valores de data nos arquivos de dados a serem carregados. |
TIMESTAMPFORMAT |
TIMESTAMP_FORMAT |
CSV |
String que define o formato dos valores de carimbo de data/hora nos arquivos de dados a serem carregados. |
Se o parâmetro usado não estiver na lista, a API gera um erro.
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1011¶
Mensagem: pyspark.sql.dataframe.DataFrameStatFunctions.approxQuantile tem uma solução alternativa
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.dataframe.DataFrameStatFunctions.approxQuantile que tem uma solução alternativa.
Cenário¶
Entrada
É importante entender que o Pyspark usa duas funções approxQuantile diferentes; aqui usamos a versão DataFrameStatFunctions approxQuantile.
import tempfile
from pyspark.sql import SparkSession, DataFrameStatFunctions
spark = SparkSession.builder.getOrCreate()
data = [['Q1', 300000],
['Q2', 60000],
['Q3', 500002],
['Q4', 130000]]
columns = ['Quarter', 'Gain']
df = spark.createDataFrame(data, columns)
aprox_quantille = DataFrameStatFunctions(df).approxQuantile('Gain', [0.25, 0.5, 0.75], 0)
print(aprox_quantille)
Saída
O SMA retorna o EWI SPRKPY1011 sobre a linha em que approxQuantile é usado, para que você possa identificar onde corrigir.
import tempfile
from snowflake.snowpark import Session, DataFrameStatFunctions
spark = Session.builder.getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":0,"minor":0,"patch":0},"attributes":{"language":"Python"}})
data = [['Q1', 300000],
['Q2', 60000],
['Q3', 500002],
['Q4', 130000]]
columns = ['Quarter', 'Gain']
df = spark.createDataFrame(data, columns)
#EWI: SPRKPY1011 => pyspark.sql.dataframe.DataFrameStatFunctions.approxQuantile has a workaround, see documentation for more info
aprox_quantille = DataFrameStatFunctions(df).approxQuantile('Gain', [0.25, 0.5, 0.75], 0)
Correção recomendada
Você pode usar o método aproxQuantile do Snowpark. Alguns parâmetros não correspondem, e por isso exigem ajustes manuais. Para o exemplo do código de saída, uma correção recomendada poderia ser:
from snowflake.snowpark import Session # remove DataFrameStatFunctions because is not required
...
df = spark.createDataFrame(data, columns)
aprox_quantille = df.stat.approx_quantile('Ammount', [0.25, 0.5, 0.75])
pyspark.sql.dataframe.DataFrame.approxQuantile relativeError parameter não existe no SnowPark.
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1040¶
Aviso
Este código de problema está obsoleto
Mensagem: pyspark.sql.functions.explode tem uma solução alternativa, consulte a documentação para obter mais informações
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.sql.functions.explode, que tem uma solução alternativa.
Cenário¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.functions.explode
que gera esse EWI. Neste exemplo, a função explode
é usada para gerar uma linha por item de matriz para a coluna numbers.
df = spark.createDataFrame([("Alice", [1, 2, 3]), ("Bob", [4, 5]), ("Charlie", [6, 7, 8, 9])], ["name", "numbers"])
exploded_df = df.select("name", explode(df.numbers).alias("number"))
Saída
O SMA adiciona o EWI SPRKPY1040
ao código de saída para que você saiba que essa função não é diretamente compatível com o Snowpark, mas tem uma solução alternativa.
df = spark.createDataFrame([("Alice", [1, 2, 3]), ("Bob", [4, 5]), ("Charlie", [6, 7, 8, 9])], ["name", "numbers"])
#EWI: SPRKPY1040 => pyspark.sql.functions.explode has a workaround, see documentation for more info
exploded_df = df.select("name", explode(df.numbers).alias("number"))
Correção recomendada
Como solução alternativa, você pode importar o pacote snowpark_extensions, que fornece uma extensão para a função explode
.
import snowpark_extensions
df = spark.createDataFrame([("Alice", [1, 2, 3]), ("Bob", [4, 5]), ("Charlie", [6, 7, 8, 9])], ["name", "numbers"])
exploded_df = df.select("name", explode(df.numbers).alias("number"))
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1074¶
Mensagem: O arquivo tem indentação mista (espaços e tabulações).
Categoria: Erro de análise.
Descrição¶
Esse problema aparece quando a ferramenta detecta que o arquivo tem um recuo misto. Isso significa que o arquivo tem uma combinação de espaços e tabulações para recuar as linhas de código.
Cenário¶
Entrada
No Pyspark, você pode misturar espaços e tabulações para o nível de identificação.
def foo():
x = 5 # spaces
y = 6 # tab
Saída
O SMA não pode lidar com marcadores de recuo mistos. Quando isso é detectado em um arquivo de código python, o SMA adiciona o EWI SPRKPY1074 na primeira linha.
## EWI: SPRKPY1074 => File has mixed indentation (spaces and tabs).
## This file was not converted, so it is expected to still have references to the Spark API
def foo():
x = 5 # spaces
y = 6 # tabs
Correção recomendada
A solução é fazer com que todos os símbolos de recuo sejam iguais.
def foo():
x = 5 # tab
y = 6 # tab
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
¶
SPRKPY1025¶
Aviso
Este código de problema está obsoleto
Mensagem: pyspark.sql.functions.ntile tem uma solução alternativa, consulte a documentação para obter mais informações
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.sql.functions.ntile, que tem uma solução alternativa.
Cenário¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.functions.ntile
que gera esse EWI. Neste exemplo, a função ntile
é usada para dividir as linhas em 3 compartimentos.
df = spark.createDataFrame([("Alice", 50), ("Bob", 30), ("Charlie", 60), ("David", 90), ("Eve", 70), ("Frank", 40)], ["name", "score"])
windowSpec = Window.orderBy("score")
df_with_ntile = df.withColumn("bucket", ntile(3).over(windowSpec))
Saída
O SMA adiciona o EWI SPRKPY1025
ao código de saída para que você saiba que essa função não é diretamente compatível com o Snowpark, mas tem uma solução alternativa.
df = spark.createDataFrame([("Alice", 50), ("Bob", 30), ("Charlie", 60), ("David", 90), ("Eve", 70), ("Frank", 40)], ["name", "score"])
windowSpec = Window.orderBy("score")
#EWI: SPRKPY1025 => pyspark.sql.functions.ntile has a workaround, see documentation for more info
df_with_ntile = df.withColumn("bucket", ntile(3).over(windowSpec))
Correção recomendada
O Snowpark tem uma função ntile equivalente, mas o argumento passado para ela deve ser uma coluna. Como solução alternativa, você pode converter o argumento literal em uma coluna usando a função snowflake.snowpark.functions.lit.
df = spark.createDataFrame([("Alice", 50), ("Bob", 30), ("Charlie", 60), ("David", 90), ("Eve", 70), ("Frank", 40)], ["name", "score"])
windowSpec = Window.orderBy("score")
df_with_ntile = df.withColumn("bucket", ntile(lit(3)).over(windowSpec))
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1087¶
Mensagem: A função pyspark.sql.dataframe.DataFrame.writeTo não é suportada, mas tem uma solução alternativa.
Categoria: Aviso.
Descrição¶
A função pyspark.sql.dataframe.DataFrame.writeTo não é suportada. A solução alternativa é usar o método do Snowpark DataFrameWriter SaveAsTable.
Cenário¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.dataframe.DataFrame.writeTo
, o dataframe df
é gravado em uma tabela com o nome Personal_info
.
df = spark.createDataFrame([["John", "Berry"], ["Rick", "Berry"], ["Anthony", "Davis"]],
schema=["FIRST_NAME", "LAST_NAME"])
df.writeTo("Personal_info")
Saída
O SMA adiciona o EWI SPRKPY1087
ao código de saída para informar que essa função não é compatível, mas tem uma solução alternativa.
df = spark.createDataFrame([["John", "Berry"], ["Rick", "Berry"], ["Anthony", "Davis"]],
schema=["FIRST_NAME", "LAST_NAME"])
#EWI: SPRKPY1087 => pyspark.sql.dataframe.DataFrame.writeTo is not supported, but it has a workaround.
df.writeTo("Personal_info")
Correção recomendada
A solução alternativa é usar o método do Snowpark DataFrameWriter SaveAsTable.
df = spark.createDataFrame([["John", "Berry"], ["Rick", "Berry"], ["Anthony", "Davis"]],
schema=["FIRST_NAME", "LAST_NAME"])
df.write.saveAsTable("Personal_info")
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1035¶
Aviso
Este código de problema está obsoleto
Mensagem: pyspark.sql.functions.reverse tem uma solução alternativa, consulte a documentação para obter mais informações
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.sql.functions.reverse, que tem uma solução alternativa.
Cenário¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.functions.reverse
que gera esse EWI. Neste exemplo, a função reverse
é usada para inverter cada cadeia de caracteres da coluna word.
df = spark.createDataFrame([("hello",), ("world",)], ["word"])
df_reversed = df.withColumn("reversed_word", reverse(df["word"]))
df_reversed = df.withColumn("reversed_word", reverse("word"))
Saída
O SMA adiciona o EWI SPRKPY1035
ao código de saída para que você saiba que essa função não é diretamente compatível com o Snowpark, mas tem uma solução alternativa.
df = spark.createDataFrame([("hello",), ("world",)], ["word"])
#EWI: SPRKPY1035 => pyspark.sql.functions.reverse has a workaround, see documentation for more info
df_reversed = df.withColumn("reversed_word", reverse(df["word"]))
#EWI: SPRKPY1035 => pyspark.sql.functions.reverse has a workaround, see documentation for more info
df_reversed = df.withColumn("reversed_word", reverse("word"))
Correção recomendada
Como solução alternativa, você pode importar o pacote snowpark_extensions, que fornece uma extensão para a função reverse
.
import snowpark_extensions
df = spark.createDataFrame([("hello",), ("world",)], ["word"])
df_reversed = df.withColumn("reversed_word", reverse(df["word"]))
df_reversed = df.withColumn("reversed_word", reverse("word"))
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1064¶
Mensagem: O elemento _ Spark _ não se aplica, pois o snowflake usa o mecanismo snowpipe.
Categoria: Aviso
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de qualquer elemento da biblioteca pyspark.streaming:
pyspark.streaming.listener.StreamingListener.
Cenário¶
Entrada
Abaixo está um exemplo com um dos elementos que acionam esse EWI.
from pyspark.streaming.listener import StreamingListener
var = StreamingListener.Java
var.mro()
df = spark.createDataFrame([(25, "Alice", "150"), (30, "Bob", "350")], schema=["age", "name", "value"])
df.show()
Saída
O SMA adiciona o EWI SPRKPY1064
no código de saída para que você saiba que essa função não se aplica.
#EWI: SPRKPY1064 => The element does not apply since snowflake uses snowpipe mechanism instead.
var = StreamingListener.Java
var.mro()
df = spark.createDataFrame([(25, "Alice", "150"), (30, "Bob", "350")], schema=["age", "name", "value"])
df.show()
Correção recomendada
O SMA remove a instrução de importação e adiciona o problema ao inventário Issues.csv, removendo todos os usos do elemento Spark.
df = spark.createDataFrame([(25, "Alice", "150"), (30, "Bob", "350")], schema=["age", "name", "value"])
df.show()
Recomendações adicionais¶
Verifique a documentação do Snowpipe para ver como ele se encaixa no cenário atual.
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1050¶
Mensagem: pyspark.conf.SparkConf.set tem uma solução alternativa
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso do pyspark.conf.SparkConf.set que tem uma solução alternativa.
Cenário¶
Entrada
Abaixo está um exemplo que define uma variável usando conf.set
.
conf = SparkConf().setAppName('my_app')
conf.set("spark.storage.memoryFraction", "0.5")
Saída
A ferramenta adiciona o EWI SPRKPY1050
indicando que uma solução alternativa pode ser implementada.
conf = SparkConf().setAppName('my_app')
#EWI: SPRKPY1050 => pyspark.conf.SparkConf.set has a workaround, see documentation for more info
conf.set("spark.storage.memoryFraction", "0.5")
Correção recomendada
SparkConf.set é usado para definir uma configuração usada somente pelo Pyspark e não se aplica ao Snowpark. Você pode remover ou comentar o código
#conf.set("spark.storage.memoryFraction", "0.5")
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1001¶
Message : Esta seção de código tem erros de análise
Category : Erro de análise.
Descrição¶
Um erro de análise é relatado pelo Snowpark Migration Accelerator (SMA) quando ele não consegue ler ou entender corretamente o código em um arquivo (não consegue «analisar» corretamente o arquivo). Esse código de problema aparece quando um arquivo tem um ou mais erros de análise.
Cenário ¶
Entrada: A mensagem EWI é exibida quando o código tem sintaxe inválida, por exemplo:
def foo():
x = %%%%%%1###1
Saída: O SMA encontra um erro de análise e comenta o erro de análise adicionando a mensagem EWI correspondente:
def foo():
x
## EWI: SPRKPY1101 => Unrecognized or invalid CODE STATEMENT @(2, 7). Last valid token was 'x' @(2, 5), failed token '=' @(2, 7)
## = %%%%%%1###1
Recomendações adicionais ¶
Verifique se o arquivo contém código Python válido. (Você pode usar o arquivo issues.csv para localizar todos os arquivos com esse código EWI para determinar quais arquivos não foram processados pela ferramenta devido a erros de análise) Muitos erros de análise ocorrem porque apenas parte do código é inserida na ferramenta, portanto, é importante garantir que o código seja executado na fonte. Se for válido, informe que encontrou um erro de análise usando a opção de Relatar um problema no SMA. Inclua a linha de código que estava causando o erro de análise na descrição quando registrar esse problema.
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1021¶
Aviso
Este código de problema está obsoleto
Mensagem: pyspark.sql.functions.last tem uma solução alternativa, consulte a documentação para obter mais informações
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.sql.functions.last, que tem uma solução alternativa.
Cenário¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.functions.last
que gera esse EWI. Neste exemplo, a função last
é usada para obter o último valor **** para cada nome.
df = spark.createDataFrame([("Alice", 1), ("Bob", 2), ("Charlie", 3), ("Alice", 4), ("Bob", 5)], ["name", "value"])
df_grouped = df.groupBy("name").agg(last("value").alias("last_value"))
Saída
O SMA adiciona o EWI SPRKPY1021
ao código de saída para que você saiba que essa função não é diretamente compatível com o Snowpark, mas tem uma solução alternativa.
df = spark.createDataFrame([("Alice", 1), ("Bob", 2), ("Charlie", 3), ("Alice", 4), ("Bob", 5)], ["name", "value"])
#EWI: SPRKPY1021 => pyspark.sql.functions.last has a workaround, see documentation for more info
df_grouped = df.groupBy("name").agg(last("value").alias("last_value"))
Correção recomendada
Como solução alternativa, você pode usar a função Snowflake LAST_VALUE. Para invocar essa função do Snowpark, use a função snowflake.snowpark.functions.call_builtin e passe a cadeia de cadeia de caracteres last_value
como o primeiro argumento e a coluna correspondente como o segundo argumento. Se estava usando o nome da coluna na função last
, deve convertê-lo em uma coluna ao chamar a função call_builtin
.
df = spark.createDataFrame([("Alice", 1), ("Bob", 2), ("Charlie", 3), ("Alice", 4), ("Bob", 5)], ["name", "value"])
df_grouped = df.groupBy("name").agg(call_builtin("last_value", col("value")).alias("last_value"))
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
descrição: >- O parâmetro mode
nos métodos CSV, JSON e PARQUET é transformado em overwrite
SPRKPY1070¶
Mensagem: O argumento mode
é transformado em overwrite
, verifica o valor da variável e define o valor bool correspondente.
Categoria: Aviso
Descrição¶
Quando há um uso de:
A ferramenta analisa o parâmetro mode
para determinar se o valor é overwrite
.
Cenários¶
Cenário 1¶
Código de entrada
Para esse cenário, a ferramenta detecta que o parâmetro mode pode definir o valor bool correspondente.
df.write.csv(file_path, mode="overwrite")
Código de saída:
A ferramenta SMA analisa o parâmetro mode, determina que o valor é overwrite
e define o valor bool correspondente
df.write.csv(file_path, format_type_options = dict(compression = "None"), overwrite = True)
Correção recomendada
Não há uma correção recomendada para esse cenário porque a ferramenta realizou a transformação correspondente.
Cenário 2:
Código de entrada
Nesse cenário, a ferramenta não pode validar se o valor é overwrite
.
df.write.csv(file_path, mode=myVal)
Código de saída:
O SMA adiciona uma mensagem EWI indicando que o parâmetro mode foi transformado em “overwrite”, mas também serve para que você saiba que é melhor verificar o valor da variável e definir o valor bool correto.
#EWI: SPRKPY1070 => The 'mode' argument is transformed to 'overwrite', check the variable value and set the corresponding bool value.
df.write.csv(file_path, format_type_options = dict(compression = "None"), overwrite = myVal)
Correção recomendada
Verifique o valor do parâmetro mode
e adicione o valor correto para o parâmetro overwrite
.
df.write.csv(file_path, format_type_options = dict(compression = "None"), overwrite = True)
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1083¶
Mensagem: A função pyspark.sql.readwriter.DataFrameWriter.save não é suportada. Uma solução alternativa é usar o método copy_into_location do Snowpark DataFrameWriter.
Categoria: Aviso
Descrição¶
A função pyspark.sql.readwriter.DataFrameWriter.save não é suportada. A solução alternativa é usar os métodos do Snowpark DataFrameWriter.
Cenários¶
A assinatura spark para esse método DataFrameWriter. save(path, format, mode, partitionBy, **options)
não existe no Snowpark. Portanto, qualquer uso da função load terá um EWI no código de saída.
Cenário 1¶
Código de entrada
Abaixo está um exemplo que tenta salvar dados no formato CSV
.
path_csv_file = "/path/to/file.csv"
data = [
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = my_session.createDataFrame(data, schema=["Name", "Age", "City"])
df.write.save(path_csv_file, format="csv")
df.write.save(path_csv_file, format="csv", mode="overwrite")
df.write.save(path_csv_file, format="csv", mode="overwrite", lineSep="\r\n", dateFormat="YYYY/MM/DD")
df.write.save(path_csv_file, format="csv", mode="overwrite", partitionBy="City", lineSep="\r\n", dateFormat="YYYY/MM/DD")
Código de saída
A ferramenta adiciona esse EWI SPRKPY1083
no código de saída para que você saiba que essa função não é compatível com o Snowpark, mas há uma solução alternativa.
path_csv_file = "/path/to/file.csv"
data = [
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = my_session.createDataFrame(data, schema=["Name", "Age", "City"])
#EWI: SPRKPY1083 => The pyspark.sql.readwriter.DataFrameWriter.save function is not supported. A workaround is to use Snowpark DataFrameWriter copy_into_location method instead.
df.write.save(path_csv_file, format="csv")
#EWI: SPRKPY1083 => The pyspark.sql.readwriter.DataFrameWriter.save function is not supported. A workaround is to use Snowpark DataFrameWriter copy_into_location method instead.
df.write.save(path_csv_file, format="csv", mode="overwrite")
#EWI: SPRKPY1083 => The pyspark.sql.readwriter.DataFrameWriter.save function is not supported. A workaround is to use Snowpark DataFrameWriter copy_into_location method instead.
df.write.save(path_csv_file, format="csv", mode="overwrite", lineSep="\r\n", dateFormat="YYYY/MM/DD")
#EWI: SPRKPY1083 => The pyspark.sql.readwriter.DataFrameWriter.save function is not supported. A workaround is to use Snowpark DataFrameWriter copy_into_location method instead.
df.write.save(path_csv_file, format="csv", mode="overwrite", partitionBy="City", lineSep="\r\n", dateFormat="YYYY/MM/DD")
Correção recomendada
Como solução alternativa, você pode usar os métodos do Snowpark DataFrameWriter.
Correção dos parâmetros
path
eformat
:Substitua o método
load
pelo método csv ou copy_into_location.Se estiver usando o método
copy_into_location
, precisará especificar o formato com o parâmetrofile_format_type
.O primeiro parâmetro
path
deve estar em um estágio para fazer uma equivalência com o Snowpark.
Abaixo está um exemplo que cria um estágio temporal e coloca o arquivo nele, depois chama um dos métodos mencionados acima.
data = [
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
## Stage creation
temp_stage = f'{Session.get_fully_qualified_current_schema()}.{_generate_prefix("TEMP_STAGE")}'
my_session.sql(f'CREATE TEMPORARY STAGE IF NOT EXISTS {temp_stage}').show()
my_session.file.put(f"file:///path/to/file.csv", f"@{temp_stage}")
stage_file_path = f"{temp_stage}file.csv"
## Using csv method
df.write.csv(stage_file_path)
## Using copy_into_location method
df.write.copy_into_location(stage_file_path, file_format_type="csv")
Corrigindo o parâmetro
mode
:Use a função mode do Snowpark DataFrameWriter, como segue:
Abaixo está um exemplo que adiciona à cadeia em margarida o método mode
com overwrite
como parâmetro.
data = [
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
## Using csv method
df.write.mode("overwrite").csv(temp_stage)
## Using copy_into_location method
df.write.mode("overwrite").copy_into_location(temp_stage, file_format_type="csv")
Correção do parâmetro
partitionBy
:Use o parâmetro partition_by do método
CSV
, como segue:
Abaixo está um exemplo que usou o parâmetro partition_by
do método CSV
.
data = [
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
## Using csv method
df.write.csv(temp_stage, partition_by="City")
## Using copy_into_location method
df.write.copy_into_location(temp_stage, file_format_type="csv", partition_by="City")
Correção do parâmetro
options
:Use o parâmetro format_type_options do método
CSV
, como segue:
As opções entre o spark e o snowpark não são as mesmas. Nesse caso, lineSep
e dateFormat
são substituídos por RECORD_DELIMITER
e DATE_FORMAT
, a seção Additional recommendations tem uma tabela com todas as equivalências.
Abaixo está um exemplo que cria um dicionário com RECORD_DELIMITER
e DATE_FORMAT
e chama o método options
com esse dicionário.
data = [
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
optionsParam = {"RECORD_DELIMITER": "\r\n", "DATE_FORMAT": "YYYY/MM/DD"}
## Using csv method
df.write.csv(stage, format_type_options=optionsParam)
## Using copy_into_location method
df.write.csv(stage, file_format_type="csv", format_type_options=optionsParam)
Cenário 2¶
Código de entrada
Abaixo está um exemplo que tenta salvar dados no formato JSON
.
path_json_file = "/path/to/file.json"
data = [
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
df.write.save(path_json_file, format="json")
df.write.save(path_json_file, format="json", mode="overwrite")
df.write.save(path_json_file, format="json", mode="overwrite", dateFormat="YYYY/MM/DD", timestampFormat="YYYY-MM-DD HH24:MI:SS.FF3")
df.write.save(path_json_file, format="json", mode="overwrite", partitionBy="City", dateFormat="YYYY/MM/DD", timestampFormat="YYYY-MM-DD HH24:MI:SS.FF3")
Código de saída
A ferramenta adiciona esse EWI SPRKPY1083
no código de saída para que você saiba que essa função não é compatível com o Snowpark, mas há uma solução alternativa.
path_json_file = "/path/to/file.json"
data = [
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
#EWI: SPRKPY1083 => The pyspark.sql.readwriter.DataFrameWriter.save function is not supported. A workaround is to use Snowpark DataFrameWriter copy_into_location method instead.
df.write.save(path_json_file, format="json")
#EWI: SPRKPY1083 => The pyspark.sql.readwriter.DataFrameWriter.save function is not supported. A workaround is to use Snowpark DataFrameWriter copy_into_location method instead.
df.write.save(path_json_file, format="json", mode="overwrite")
#EWI: SPRKPY1083 => The pyspark.sql.readwriter.DataFrameWriter.save function is not supported. A workaround is to use Snowpark DataFrameWriter copy_into_location method instead.
df.write.save(path_json_file, format="json", mode="overwrite", dateFormat="YYYY/MM/DD", timestampFormat="YYYY-MM-DD HH24:MI:SS.FF3")
#EWI: SPRKPY1083 => The pyspark.sql.readwriter.DataFrameWriter.save function is not supported. A workaround is to use Snowpark DataFrameWriter copy_into_location method instead.
df.write.save(path_json_file, format="json", mode="overwrite", partitionBy="City", dateFormat="YYYY/MM/DD", timestampFormat="YYYY-MM-DD HH24:MI:SS.FF3")
Correção recomendada
Como solução alternativa, você pode usar os métodos do Snowpark DataFrameReader.
Correção dos parâmetros
path
eformat
:Substitua o método
load
pelo método json ou copy_into_locationSe estiver usando o método
copy_into_location
, precisará especificar o formato com o parâmetrofile_format_type
.O primeiro parâmetro
path
deve estar em um estágio para fazer uma equivalência com o Snowpark.
Abaixo está um exemplo que cria um estágio temporal e coloca o arquivo nele, depois chama um dos métodos mencionados acima.
data = [
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
## Stage creation
temp_stage = f'{Session.get_fully_qualified_current_schema()}.{_generate_prefix("TEMP_STAGE")}'
my_session.sql(f'CREATE TEMPORARY STAGE IF NOT EXISTS {temp_stage}').show()
my_session.file.put(f"file:///path/to/file.json", f"@{temp_stage}")
stage_file_path = f"{temp_stage}file.json"
## Using json method
df.write.json(stage_file_path)
## Using copy_into_location method
df.write.copy_into_location(stage_file_path, file_format_type="json")
Corrigindo o parâmetro
mode
:Use a função mode do Snowpark DataFrameWriter, como segue:
Abaixo está um exemplo que adiciona à cadeia em margarida o método mode
com overwrite
como parâmetro.
data = [
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
## Using json method
df.write.mode("overwrite").json(temp_stage)
## Using copy_into_location method
df.write.mode("overwrite").copy_into_location(temp_stage, file_format_type="json")
Correção do parâmetro
partitionBy
:Use o parâmetro partition_by do método
CSV
, como segue:
Abaixo está um exemplo que usou o parâmetro partition_by
do método CSV
.
data = [
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
## Using json method
df.write.json(temp_stage, partition_by="City")
## Using copy_into_location method
df.write.copy_into_location(temp_stage, file_format_type="json", partition_by="City")
Correção do parâmetro
options
:Use o parâmetro format_type_options do método
CSV
, como segue:
As opções entre o spark e o snowpark não são as mesmas. Nesse caso, dateFormat
e timestampFormat
são substituídos por DATE_FORMAT
e TIMESTAMP_FORMAT
, a seção Additional recommendations tem uma tabela com todas as equivalências.
Abaixo está um exemplo que cria um dicionário com DATE_FORMAT
e TIMESTAMP_FORMAT
e chama o método options
com esse dicionário.
data = [
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
optionsParam = {"DATE_FORMAT": "YYYY/MM/DD", "TIMESTAMP_FORMAT": "YYYY-MM-DD HH24:MI:SS.FF3"}
## Using json method
df.write.json(stage, format_type_options=optionsParam)
## Using copy_into_location method
df.write.copy_into_location(stage, file_format_type="json", format_type_options=optionsParam)
Cenário 3¶
Código de entrada
Abaixo está um exemplo que tenta salvar dados no formato PARQUET
.
path_parquet_file = "/path/to/file.parquet"
data = [
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
df.write.save(path_parquet_file, format="parquet")
df.write.save(path_parquet_file, format="parquet", mode="overwrite")
df.write.save(path_parquet_file, format="parquet", mode="overwrite", pathGlobFilter="*.parquet")
df.write.save(path_parquet_file, format="parquet", mode="overwrite", partitionBy="City", pathGlobFilter="*.parquet")
Código de saída
A ferramenta adiciona esse EWI SPRKPY1083
no código de saída para que você saiba que essa função não é compatível com o Snowpark, mas há uma solução alternativa.
path_parquet_file = "/path/to/file.parquet"
data = [
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
#EWI: SPRKPY1083 => The pyspark.sql.readwriter.DataFrameWriter.save function is not supported. A workaround is to use Snowpark DataFrameWriter copy_into_location method instead.
df.write.save(path_parquet_file, format="parquet")
#EWI: SPRKPY1083 => The pyspark.sql.readwriter.DataFrameWriter.save function is not supported. A workaround is to use Snowpark DataFrameWriter copy_into_location method instead.
df.write.save(path_parquet_file, format="parquet", mode="overwrite")
#EWI: SPRKPY1083 => The pyspark.sql.readwriter.DataFrameWriter.save function is not supported. A workaround is to use Snowpark DataFrameWriter copy_into_location method instead.
df.write.save(path_parquet_file, format="parquet", mode="overwrite", pathGlobFilter="*.parquet")
#EWI: SPRKPY1083 => The pyspark.sql.readwriter.DataFrameWriter.save function is not supported. A workaround is to use Snowpark DataFrameWriter copy_into_location method instead.
df.write.save(path_parquet_file, format="parquet", mode="overwrite", partitionBy="City", pathGlobFilter="*.parquet")
Correção recomendada
Como solução alternativa, você pode usar os métodos do Snowpark DataFrameReader.
Correção dos parâmetros
path
eformat
:Substitua o método
load
pelo método parquet ou copy_into_location.Se estiver usando o método
copy_into_location
, precisará especificar o formato com o parâmetrofile_format_type
.O primeiro parâmetro
path
deve estar em um estágio para fazer uma equivalência com o Snowpark.
Abaixo está um exemplo que cria um estágio temporal e coloca o arquivo nele, depois chama um dos métodos mencionados acima.
data = [
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
## Stage creation
temp_stage = f'{Session.get_fully_qualified_current_schema()}.{_generate_prefix("TEMP_STAGE")}'
my_session.sql(f'CREATE TEMPORARY STAGE IF NOT EXISTS {temp_stage}').show()
my_session.file.put(f"file:///path/to/file.parquet", f"@{temp_stage}")
stage_file_path = f"{temp_stage}file.parquet"
## Using parquet method
df.write.parquet(stage_file_path)
## Using copy_into_location method
df.write.copy_into_location(stage, file_format_type="parquet")
Corrigindo o parâmetro
mode
:Use a função mode do Snowpark DataFrameWriter, como segue:
Abaixo está um exemplo que adiciona à cadeia em margarida o método mode
com overwrite
como parâmetro.
data = [
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
## Using parquet method
df.write.mode("overwrite").parquet(temp_stage)
## Using copy_into_location method
df.write.mode("overwrite").copy_into_location(stage, file_format_type="parquet")
Correção do parâmetro
partitionBy
:Use o parâmetro partition_by do método
CSV
, como segue:
Abaixo está um exemplo que usou o parâmetro partition_by
do método parquet
.
data = [
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
## Using parquet method
df.write.parquet(temp_stage, partition_by="City")
## Using copy_into_location method
df.write.copy_into_location(stage, file_format_type="parquet", partition_by="City")
Correção do parâmetro
options
:Use o parâmetro format_type_options do método
CSV
, como segue:
As opções entre spark e snowpark não são as mesmas. Nesse caso, pathGlobFilter
é substituído por PATTERN
, a seção Additional recommendations tem uma tabela com todas as equivalências.
Abaixo está um exemplo que cria um dicionário com PATTERN
e chama o método options
com esse dicionário.
data = [
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
optionsParam = {"PATTERN": "*.parquet"}
## Using parquet method
df.write.parquet(stage, format_type_options=optionsParam)
## Using copy_into_location method
df.write.copy_into_location(stage, file_format_type="parquet", format_type_options=optionsParam)
Recomendações adicionais¶
Leve em conta que as opções entre o spark e o snowpark não são as mesmas, mas podem ser mapeadas:
Opções do Spark |
Valor possível |
Equivalente do Snowpark |
Descrição |
---|---|---|---|
header |
Verdadeiro ou falso |
SKIP_HEADER = 1 / SKIP_HEADER = 0 |
Para usar a primeira linha de um arquivo como nomes de colunas. |
delimiter |
Qualquer separador de campo de um ou vários caracteres |
FIELD_DELIMITER |
Para especificar caractere(s) único(s)/múltiplo(s) como separador para cada coluna/campo. |
sep |
Qualquer separador de campo de caractere único |
FIELD_DELIMITER |
Para especificar um único caractere como separador para cada coluna/campo. |
encoding |
UTF-8, UTF-16, etc… |
ENCODING |
Para decodificar os arquivos CSV pelo tipo de codificação fornecido. A codificação padrão é UTF-8 |
lineSep |
Qualquer separador de linha de caractere único |
RECORD_DELIMITER |
Para definir o separador de linha que deve ser usado na análise de arquivos. |
pathGlobFilter |
Padrão de arquivo |
PATTERN |
Para definir um padrão para ler arquivos somente com nomes de arquivos que correspondam ao padrão. |
recursiveFileLookup |
Verdadeiro ou falso |
N/A |
Para examinar recursivamente um diretório para ler arquivos. O valor padrão dessa opção é False. |
quote |
Caractere único a ser citado |
FIELD_OPTIONALLY_ENCLOSED_BY |
Para citar campos/colunas que contêm campos em que o delimitador/separador pode fazer parte do valor. Esse caractere Para citar todos os campos quando usado com a opção quoteAll. O valor padrão dessa opção é aspas duplas («). |
nullValue |
Cadeia de caracteres para substituir null |
NULL_IF |
Para substituir os valores nulos pela cadeia de caracteres durante a leitura e gravação do dataframe. |
dateFormat |
Formato de data válido |
DATE_FORMAT |
Para definir uma cadeia de caracteres que indica um formato de data. O formato padrão é yyyy-MM-dd. |
timestampFormat |
Formato de carimbo de data/hora válido |
TIMESTAMP_FORMAT |
Para definir uma cadeia de caracteres que indica um formato de carimbo de data/hora. O formato padrão é yyyy-MM-dd “T’HH:mm:ss. |
escape |
Qualquer caractere único |
ESCAPE |
Para definir um único caractere como caractere de escape para substituir o caractere de escape padrão (\). |
inferSchema |
Verdadeiro ou falso |
INFER_SCHEMA |
Detecta automaticamente o esquema do arquivo |
mergeSchema |
Verdadeiro ou falso |
N/A |
Não é necessário no snowflake, pois isso acontece sempre que o infer_schema determina a estrutura do arquivo parquet |
Para a opção modifiedBefore / modifiedAfter, você pode obter o mesmo resultado no Snowflake usando as colunas de metadados e, em seguida, adicionar um filtro como:
df.filter(METADATA_FILE_LAST_MODIFIED > 'some_date')
.Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1044¶
Aviso
Esse código de problema foi depreciado desde o Spark Conversion Core Version 2.4.0
Mensagem: pyspark.sql.functions.split tem uma solução alternativa
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.functions.split, que tem uma solução alternativa.
Cenários¶
Há alguns cenários, dependendo da quantidade de parâmetros passados para o método.
Cenário 1¶
Entrada
Abaixo está um exemplo quando a função split
tem apenas os parâmetros str e pattern
F.split('col', '\\|')
Saída
A ferramenta mostra o EWI SPRKPY1044
indicando que há uma solução alternativa.
#EWI: SPRKPY1044 => pyspark.sql.functions.split has a workaround, see the documentation for more info
F.split('col', '\\|')
Correção recomendada
Como solução alternativa, você pode chamar a função snowflake.snowpark.functions.lit com o parâmetro pattern e enviá-la para a divisão.
F.split('col', lit('\\|'))
## the result of lit will be sent to the split function
Cenário 2¶
Entrada
Abaixo está outro exemplo quando a função split
tem os parâmetros str, pattern e limit.
F.split('col', '\\|', 2)
Saída
A ferramenta mostra o EWI SPRKPY1044
indicando que há uma solução alternativa.
#EWI: SPRKPY1044 => pyspark.sql.functions.split has a workaround, see the documentation for more info
F.split('col', '\\|', 2)
Correção recomendada
Esse cenário específico não é suportado.
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1015¶
Mensagem: pyspark.sql.functions.atanh tem uma solução alternativa
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.functions.atanh, que tem uma solução alternativa.
Cenário¶
Entrada
Nesse exemplo, o pyspark calcula o atanh para um dataframe usando pyspark.sql.functions.atanh.
from pyspark.sql import SparkSession
from pyspark.sql.functions import atanh
spark = SparkSession.builder.getOrCreate()
data = [['V1', 0.14],
['V2', 0.32],
['V3', 0.4],
['V4', -0.36]]
columns = ['Paremeter', 'value']
df = spark.createDataFrame(data, columns)
df_result = df.withColumn("atanh_value", atanh(df["value"]))
Saída
SMA retorna o EWI SPRKPY1015 sobre a linha em que atanh é usado, para que você possa usar para identificar onde corrigir.
from snowflake.snowpark import Session
spark = Session.builder.getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":0,"minor":0,"patch":0},"attributes":{"language":"Python"}})
data = [['V1', 0.14],
['V2', 0.32],
['V3', 0.4],
['V4', -0.36]]
columns = ['Paremeter', 'value']
df = spark.createDataFrame(data, columns)
#EWI: SPRKPY1015 => pyspark.sql.functions.atanh has a workaround, see documentation for more info
df_result = df.withColumn("atanh_value", atanh(df["value"]))
Correção recomendada
Não há implementação direta do «atanh», mas, em vez disso, pode-se usar «call_function «, usando «atanh» como o primeiro parâmetro e colName como o segundo.
import snowflake.snowpark as snowpark
from snowflake.snowpark import Session
from snowflake.snowpark.functions import call_function, col
spark = Session.builder.getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":0,"minor":0,"patch":0},"attributes":{"language":"Python"}})
data = [['V1', 0.14],
['V2', 0.32],
['V3', 0.4],
['V4', -0.36]]
columns = ['Paremeter', 'value']
df = spark.createDataFrame(data, columns)
df_result = df.select(call_function('atanh', col('value')))
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1005¶
Aviso
Esse código de problema foi depreciado desde o Spark Conversion Core Version 4.8.0
Message : pyspark.conf.SparkConf não é necessário
Category : Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso do pyspark.conf.SparkConf que não é necessário.
Cenário¶
Entrada
SparkConf pode ser chamado sem parâmetros ou com loadDefaults.
from pyspark import SparkConf
my_conf = SparkConf(loadDefaults=True)
Saída
Em ambos os casos (com ou sem parâmetros), o SMA cria um objeto Session.builder do Snowpark:
#EWI: SPRKPY1005 => pyspark.conf.SparkConf is not required
#from pyspark import SparkConf
pass
#EWI: SPRKPY1005 => pyspark.conf.SparkConf is not required
my_conf = Session.builder.configs({"user" : "my_user", "password" : "my_password", "account" : "my_account", "role" : "my_role", "warehouse" : "my_warehouse", "database" : "my_database", "schema" : "my_schema"}).create()
Recomendações adicionais¶
Esse é um parâmetro desnecessário que está sendo removido com a inserção de um comentário de aviso. Não deve haver nenhuma ação adicional por parte do usuário.
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1054¶
Mensagem: pyspark.sql.readwriter.DataFrameReader.format não é suportado.
Categoria: Aviso.
Descrição¶
Esse problema aparece quando o pyspark.sql.readwriter.DataFrameReader.format tem um argumento que não é suportado pelo Snowpark.
Cenários¶
Há alguns cenários, dependendo do tipo de formato que você está tentando carregar. Pode ser um formato suportado
ou não suportado
.
Cenário 1¶
Entrada
A ferramenta analisa o tipo de formato que está tentando carregar; os formatos compatíveis são:
Csv
JSON
Parquet
Orc
O exemplo abaixo mostra como a ferramenta transforma o método format
ao passar um valor Csv
.
from pyspark.sql import SparkSession
spark = SparkSession.builder.getOrCreate()
df1 = spark.read.format('csv').load('/path/to/file')
Saída
A ferramenta transforma o método format
em uma chamada de método Csv
.
from snowflake.snowpark import Session
spark = Session.builder.getOrCreate()
df1 = spark.read.csv('/path/to/file')
Correção recomendada
Nesse caso, a ferramenta não mostra o EWI, o que significa que não há necessidade de correção.
Cenário 2¶
Entrada
O exemplo abaixo mostra como a ferramenta transforma o método format
ao passar um valor Jdbc
.
from snowflake.snowpark import Session
spark = Session.builder.getOrCreate()
df2 = spark.read.format('jdbc') \
.option("driver", "com.mysql.cj.jdbc.Driver") \
.option("url", "jdbc:mysql://localhost:3306/emp") \
.option("dbtable", "employee") \
.option("user", "root") \
.option("password", "root") \
.load()
Saída
A ferramenta mostra o EWI SPRKPY1054
indicando que o valor «jdbc» não é compatível.
from snowflake.snowpark import Session
spark = Session.builder.getOrCreate()
#EWI: SPRKPY1054 => pyspark.sql.readwriter.DataFrameReader.format with argument value "jdbc" is not supported.
#EWI: SPRKPY1002 => pyspark.sql.readwriter.DataFrameReader.load is not supported
df2 = spark.read.format('jdbc') \
.option("driver", "com.mysql.cj.jdbc.Driver") \
.option("url", "jdbc:mysql://localhost:3306/emp") \
.option("dbtable", "employee") \
.option("user", "root") \
.option("password", "root") \
.load()
Correção recomendada
Para os cenários não suportados
, não há nenhuma correção específica, pois isso depende dos arquivos que estão tentando ser lidos.
Cenário 3¶
Entrada
O exemplo abaixo mostra como a ferramenta transforma o método format
ao passar um CSV
, mas usando uma variável.
from snowflake.snowpark import Session
spark = Session.builder.getOrCreate()
myFormat = 'csv'
df3 = spark.read.format(myFormat).load('/path/to/file')
Saída
Como a ferramenta não consegue determinar o valor da variável em tempo de execução, mostra o EWI SPRKPY1054
indicando que o valor «» não é suportado.
from snowflake.snowpark import Session
spark = Session.builder.getOrCreate()
myFormat = 'csv'
#EWI: SPRKPY1054 => pyspark.sql.readwriter.DataFrameReader.format with argument value "" is not supported.
#EWI: SPRKPY1002 => pyspark.sql.readwriter.DataFrameReader.load is not supported
df3 = spark.read.format(myFormat).load('/path/to/file')
Correção recomendada
Como solução alternativa, você pode verificar o valor da variável e adicioná-lo como uma cadeia de caracteres à chamada format
.
Recomendações adicionais¶
O local do Snowpark só aceita locais de nuvem usando um estágio de snowflake.
A documentação dos métodos suportados pelo Snowpark pode ser encontrada na documentação
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1060¶
Mensagem: O mecanismo de autenticação é connection.json (modelo fornecido).
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso do pyspark.conf.SparkConf.
Cenário¶
Entrada
Como o mecanismo de autenticação é diferente no Snowpark, a ferramenta remove os usos e cria um arquivo de configuração de conexão (connection.json) em vez disso.
from pyspark import SparkConf
my_conf = SparkConf(loadDefaults=True)
Saída
A ferramenta adiciona o EWI SPRKPY1060
indicando que o mecanismo de autenticação é diferente.
#EWI: SPRKPY1002 => pyspark.conf.SparkConf is not supported
#EWI: SPRKPY1060 => The authentication mechanism is connection.json (template provided).
#my_conf = Session.builder.configs(connection_parameter).getOrCreate()
my_conf = None
Correção recomendada
Para criar uma conexão, é necessário preencher as informações no arquivo connection.json
.
{
"user": "<USER>",
"password": "<PASSWORD>",
"account": "<ACCOUNT>",
"role": "<ROLE>",
"warehouse": "<WAREHOUSE>",
"database": "<DATABASE>",
"schema": "<SCHEMA>"
}
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1031¶
Aviso
Esse código de problema foi depreciado desde o Spark Conversion Core 2.7.0
Mensagem: pyspark.sql.column.Column.contains tem uma solução alternativa, consulte a documentação para obter mais informações
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.sql.column.Column.contains, que tem uma solução alternativa.
Cenário¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.column.Column.contains
que gera esse EWI. Neste exemplo, a função contains
é usada para filtrar as linhas em que a coluna «City» contém a substring «New».
df = spark.createDataFrame([("Alice", "New York"), ("Bob", "Los Angeles"), ("Charlie", "Chicago")], ["Name", "City"])
df_filtered = df.filter(col("City").contains("New"))
Saída
O SMA adiciona o EWI SPRKPY1031
ao código de saída para que você saiba que essa função não é diretamente compatível com o Snowpark, mas tem uma solução alternativa.
df = spark.createDataFrame([("Alice", "New York"), ("Bob", "Los Angeles"), ("Charlie", "Chicago")], ["Name", "City"])
#EWI: SPRKPY1031 => pyspark.sql.column.Column.contains has a workaround, see documentation for more info
df_filtered = df.filter(col("City").contains("New"))
Correção recomendada
Como solução alternativa, você pode usar a função snowflake.snowpark.functions.contains passando a coluna como o primeiro argumento e o elemento a ser pesquisado como o segundo argumento. Se o elemento a ser pesquisado for um valor literal, ele deverá ser convertido em uma expressão de coluna usando a função lit
.
from snowflake.snowpark import functions as f
df = spark.createDataFrame([("Alice", "New York"), ("Bob", "Los Angeles"), ("Charlie", "Chicago")], ["Name", "City"])
df_filtered = df.filter(f.contains(col("City"), f.lit("New")))
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1020¶
Mensagem: pyspark.sql.functions.instr tem uma solução alternativa
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.functions.instr, que tem uma solução alternativa.
Cenário¶
Entrada
Aqui está um exemplo básico de uso do pyspark instr:
from pyspark.sql import SparkSession
from pyspark.sql.functions import instr
spark = SparkSession.builder.getOrCreate()
df = spark.createDataFrame([('abcd',)], ['test',])
df.select(instr(df.test, 'cd').alias('result')).collect()
Saída:
O SMA retorna o EWI SPRKPY1020 sobre a linha em que o instr é usado, para que você possa identificar onde corrigir.
from snowflake.snowpark import Session
spark = Session.builder.getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":0,"minor":0,"patch":0},"attributes":{"language":"Python"}})
df = spark.createDataFrame([('abcd',)], ['test',])
#EWI: SPRKPY1020 => pyspark.sql.functions.instr has a workaround, see documentation for more info
df.select(instr(df.test, 'cd').alias('result')).collect()
Correção recomendada
É necessária uma alteração manual usando a função charindex e alterando a ordem dos dois primeiros parâmetros.
import snowflake.snowpark as snowpark
from snowflake.snowpark import Session
from snowflake.snowpark.functions import charindex, lit
spark = Session.builder.getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":0,"minor":0,"patch":0},"attributes":{"language":"Python"}})
df = spark.createDataFrame([('abcd',)], ['test',])
df.select(charindex(lit('cd'), df.test).as_('result')).show()
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1071¶
Mensagem: A função pyspark.rdd.RDD.getNumPartitions não é necessária no Snowpark. Portanto, você deve remover todas as referências.
Categoria: Aviso
Descrição¶
Esse problema aparece quando a ferramenta encontra o uso da função pyspark.rdd.RDD.getNumPartitions. O Snowflake usa o mecanismo de microparticionamento, portanto, o uso dessa função não é necessário.
Cenário¶
Entrada
O getNumPartitions retorna a quantidade de partições em um RDD.
df = spark.createDataFrame([('2015-04-08',), ('5',), [Row(a=1, b="b")]], ['dt', 'num', 'row'])
print(df.getNumPartitions())
Saída
A ferramenta adiciona esse EWI para que você saiba que o getNumPartitions não é necessário.
df = spark.createDataFrame([('2015-04-08',), ('5',), [Row(a=1, b="b")]], ['dt', 'num', 'row'])
#EWI: SPRKPY1071 => The getNumPartitions are not required in Snowpark. So, you should remove all references.
print(df.getNumPartitions())
Correção recomendada
Remover todos os usos dessa função.
df = spark.createDataFrame([('2015-04-08',), ('5',), [Row(a=1, b="b")]], ['dt', 'num', 'row'])
Recomendações adicionais¶
Para obter mais suporte, você pode enviar um e-mail para sma-support@snowflake.com ou publicar um problema na página SMA.`
SPRKPY1082¶
Mensagem: A função pyspark.sql.readwriter.DataFrameReader.load não é suportada. Uma solução alternativa é usar o método específico do formato do Snowpark DataFrameReader (avro csv, json, orc, parquet). O parâmetro path deve ser um local de estágio.
Categoria: Aviso
Descrição¶
A função pyspark.sql.readwriter.DataFrameReader.load não é suportada. A solução alternativa é usar os métodos do Snowpark DataFrameReader.
Cenários¶
A assinatura spark para esse método DataFrameReader.load(path, format, schema, **options)
não existe no Snowpark. Portanto, qualquer uso da função load terá um EWI no código de saída.
Cenário 1¶
Entrada
Abaixo está um exemplo que tenta carregar dados de uma fonte CSV
.
path_csv_file = "/path/to/file.csv"
schemaParam = StructType([
StructField("Name", StringType(), True),
StructField("Superhero", StringType(), True)
])
my_session.read.load(path_csv_file, "csv").show()
my_session.read.load(path_csv_file, "csv", schema=schemaParam).show()
my_session.read.load(path_csv_file, "csv", schema=schemaParam, lineSep="\r\n", dateFormat="YYYY/MM/DD").show()
Saída
O SMA adiciona o EWI SPRKPY1082
para que você saiba que essa função não é compatível com o Snowpark, mas há uma solução alternativa.
path_csv_file = "/path/to/file.csv"
schemaParam = StructType([
StructField("Name", StringType(), True),
StructField("Superhero", StringType(), True)
])
#EWI: SPRKPY1082 => The pyspark.sql.readwriter.DataFrameReader.load function is not supported. A workaround is to use Snowpark DataFrameReader format specific method instead (avro csv, json, orc, parquet). The path parameter should be a stage location.
my_session.read.load(path_csv_file, "csv").show()
#EWI: SPRKPY1082 => The pyspark.sql.readwriter.DataFrameReader.load function is not supported. A workaround is to use Snowpark DataFrameReader format specific method instead (avro csv, json, orc, parquet). The path parameter should be a stage location.
my_session.read.load(path_csv_file, "csv", schema=schemaParam).show()
#EWI: The pyspark.sql.readwriter.DataFrameReader.load function is not supported. A workaround is to use Snowpark DataFrameReader format specific method instead (avro csv, json, orc, parquet). The path parameter should be a stage location.
my_session.read.load(path_csv_file, "csv", schema=schemaParam, lineSep="\r\n", dateFormat="YYYY/MM/DD").show()
Correção recomendada
Como solução alternativa, você pode usar os métodos do Snowpark DataFrameReader.
Correção dos parâmetros
path
eformat
:Substitua o método
load
pelo métodocsv
.O primeiro parâmetro
path
deve estar em um estágio para fazer uma equivalência com o Snowpark.
Abaixo está um exemplo que cria um estágio temporal e coloca o arquivo nele, depois chama o método CSV
.
path_csv_file = "/path/to/file.csv"
## Stage creation
temp_stage = f'{Session.get_fully_qualified_current_schema()}.{_generate_prefix("TEMP_STAGE")}'
my_session.sql(f'CREATE TEMPORARY STAGE IF NOT EXISTS {temp_stage}').show()
my_session.file.put(f"file:///path/to/file.csv", f"@{temp_stage}")
stage_file_path = f"{temp_stage}file.csv"
schemaParam = StructType([
StructField("Name", StringType(), True),
StructField("Superhero", StringType(), True)
])
my_session.read.csv(stage_file_path).show()
Correção do parâmetro
schema
:O esquema pode ser definido usando a função schema da seguinte forma:
schemaParam = StructType([
StructField("name", StringType(), True),
StructField("city", StringType(), True)
])
df = my_session.read.schema(schemaParam).csv(temp_stage)
Correção do parâmetro
options
:
As opções entre o spark e o snowpark não são as mesmas. Nesse caso, lineSep
e dateFormat
são substituídos por RECORD_DELIMITER
e DATE_FORMAT
. A seção de Recomendações adicionais tem uma tabela com todas as equivalências.
Abaixo está um exemplo que cria um dicionário com RECORD_DELIMITER
e DATE_FORMAT
e chama o método options
com esse dicionário.
optionsParam = {"RECORD_DELIMITER": "\r\n", "DATE_FORMAT": "YYYY/MM/DD"}
df = my_session.read.options(optionsParam).csv(stage)
Cenário 2¶
Entrada
Abaixo está um exemplo que tenta carregar dados de uma fonte JSON
.
path_json_file = "/path/to/file.json"
schemaParam = StructType([
StructField("Name", StringType(), True),
StructField("Superhero", StringType(), True)
])
my_session.read.load(path_json_file, "json").show()
my_session.read.load(path_json_file, "json", schema=schemaParam).show()
my_session.read.load(path_json_file, "json", schema=schemaParam, dateFormat="YYYY/MM/DD", timestampFormat="YYYY-MM-DD HH24:MI:SS.FF3").show()
Saída
O SMA adiciona o EWI SPRKPY1082
para que você saiba que essa função não é compatível com o Snowpark, mas há uma solução alternativa.
path_json_file = "/path/to/file.json"
schemaParam = StructType([
StructField("Name", StringType(), True),
StructField("Superhero", StringType(), True)
])
#EWI: SPRKPY1082 => The pyspark.sql.readwriter.DataFrameReader.load function is not supported. A workaround is to use Snowpark DataFrameReader format specific method instead (avro csv, json, orc, parquet). The path parameter should be a stage location.
my_session.read.load(path_json_file, "json").show()
#EWI: SPRKPY1082 => The pyspark.sql.readwriter.DataFrameReader.load function is not supported. A workaround is to use Snowpark DataFrameReader format specific method instead (avro csv, json, orc, parquet). The path parameter should be a stage location.
my_session.read.load(path_json_file, "json", schema=schemaParam).show()
#EWI: SPRKPY1082 => The pyspark.sql.readwriter.DataFrameReader.load function is not supported. A workaround is to use Snowpark DataFrameReader format specific method instead (avro csv, json, orc, parquet). The path parameter should be a stage location.
my_session.read.load(path_json_file, "json", schema=schemaParam, dateFormat="YYYY/MM/DD", timestampFormat="YYYY-MM-DD HH24:MI:SS.FF3").show()
Correção recomendada
Como solução alternativa, você pode usar os métodos do Snowpark DataFrameReader.
Correção dos parâmetros
path
eformat
:Substitua o método
load
pelo métodojson
O primeiro parâmetro
path
deve estar em um estágio para fazer uma equivalência com o Snowpark.
Abaixo está um exemplo que cria um estágio temporal e coloca o arquivo nele, depois chama o método JSON
.
path_json_file = "/path/to/file.json"
## Stage creation
temp_stage = f'{Session.get_fully_qualified_current_schema()}.{_generate_prefix("TEMP_STAGE")}'
my_session.sql(f'CREATE TEMPORARY STAGE IF NOT EXISTS {temp_stage}').show()
my_session.file.put(f"file:///path/to/file.json", f"@{temp_stage}")
stage_file_path = f"{temp_stage}file.json"
schemaParam = StructType([
StructField("Name", StringType(), True),
StructField("Superhero", StringType(), True)
])
my_session.read.json(stage_file_path).show()
Correção do parâmetro
schema
:O esquema pode ser definido usando a função schema da seguinte forma:
schemaParam = StructType([
StructField("name", StringType(), True),
StructField("city", StringType(), True)
])
df = my_session.read.schema(schemaParam).json(temp_stage)
Correção do parâmetro
options
:
As opções entre o Spark e o snowpark não são as mesmas. Nesse caso, dateFormat
e timestampFormat
são substituídos por DATE_FORMAT
e TIMESTAMP_FORMAT
. A seção Additional recommendations tem uma tabela com todas as equivalências.
Abaixo está um exemplo que cria um dicionário com DATE_FORMAT
e TIMESTAMP_FORMAT
e chama o método options
com esse dicionário.
optionsParam = {"DATE_FORMAT": "YYYY/MM/DD", "TIMESTAMP_FORMAT": "YYYY-MM-DD HH24:MI:SS.FF3"}
df = Session.read.options(optionsParam).json(stage)
Cenário 3¶
Entrada
Abaixo está um exemplo que tenta carregar dados de uma fonte PARQUET
.
path_parquet_file = "/path/to/file.parquet"
schemaParam = StructType([
StructField("Name", StringType(), True),
StructField("Superhero", StringType(), True)
])
my_session.read.load(path_parquet_file, "parquet").show()
my_session.read.load(path_parquet_file, "parquet", schema=schemaParam).show()
my_session.read.load(path_parquet_file, "parquet", schema=schemaParam, pathGlobFilter="*.parquet").show()
Saída
O SMA adiciona o EWI SPRKPY1082
para que você saiba que essa função não é compatível com o Snowpark, mas há uma solução alternativa.
path_parquet_file = "/path/to/file.parquet"
schemaParam = StructType([
StructField("Name", StringType(), True),
StructField("Superhero", StringType(), True)
])
#EWI: SPRKPY1082 => The pyspark.sql.readwriter.DataFrameReader.load function is not supported. A workaround is to use Snowpark DataFrameReader format specific method instead (avro csv, json, orc, parquet). The path parameter should be a stage location.
my_session.read.load(path_parquet_file, "parquet").show()
#EWI: SPRKPY1082 => The pyspark.sql.readwriter.DataFrameReader.load function is not supported. A workaround is to use Snowpark DataFrameReader format specific method instead (avro csv, json, orc, parquet). The path parameter should be a stage location.
my_session.read.load(path_parquet_file, "parquet", schema=schemaParam).show()
#EWI: SPRKPY1082 => The pyspark.sql.readwriter.DataFrameReader.load function is not supported. A workaround is to use Snowpark DataFrameReader format specific method instead (avro csv, json, orc, parquet). The path parameter should be a stage location.
my_session.read.load(path_parquet_file, "parquet", schema=schemaParam, pathGlobFilter="*.parquet").show()
Correção recomendada
Como solução alternativa, você pode usar os métodos do Snowpark DataFrameReader.
Correção dos parâmetros
path
eformat
:Substitua o método
load
pelo métodoparquet
O primeiro parâmetro
path
deve estar em um estágio para fazer uma equivalência com o Snowpark.
Abaixo está um exemplo que cria um estágio temporal e coloca o arquivo nele, depois chama o método PARQUET
.
path_parquet_file = "/path/to/file.parquet"
## Stage creation
temp_stage = f'{Session.get_fully_qualified_current_schema()}.{_generate_prefix("TEMP_STAGE")}'
my_session.sql(f'CREATE TEMPORARY STAGE IF NOT EXISTS {temp_stage}').show()
my_session.file.put(f"file:///path/to/file.parquet", f"@{temp_stage}")
stage_file_path = f"{temp_stage}file.parquet"
schemaParam = StructType([
StructField("Name", StringType(), True),
StructField("Superhero", StringType(), True)
])
my_session.read.parquet(stage_file_path).show()
Correção do parâmetro
schema
:O esquema pode ser definido usando a função schema da seguinte forma:
schemaParam = StructType([
StructField("name", StringType(), True),
StructField("city", StringType(), True)
])
df = my_session.read.schema(schemaParam).parquet(temp_stage)
Correção do parâmetro
options
:
As opções entre Spark e snowpark não são as mesmas; nesse caso, pathGlobFilter
é substituído por PATTERN
, a seção Additional recommendations tem uma tabela com todas as equivalências.
Abaixo está um exemplo que cria um dicionário com PATTERN
e chama o método options
com esse dicionário.
optionsParam = {"PATTERN": "*.parquet"}
df = Session.read.options(optionsParam).parquet(stage)
Recomendações adicionais¶
Leve em conta que as opções entre o spark e o snowpark não são as mesmas, mas podem ser mapeadas:
Opções do Spark |
Valor possível |
Equivalente do Snowpark |
Descrição |
---|---|---|---|
header |
Verdadeiro ou falso |
SKIP_HEADER = 1 / SKIP_HEADER = 0 |
Para usar a primeira linha de um arquivo como nomes de colunas. |
delimiter |
Qualquer separador de campo de um ou vários caracteres |
FIELD_DELIMITER |
Para especificar caractere(s) único(s)/múltiplo(s) como separador para cada coluna/campo. |
sep |
Qualquer separador de campo de caractere único |
FIELD_DELIMITER |
Para especificar um único caractere como separador para cada coluna/campo. |
encoding |
UTF-8, UTF-16, etc… |
ENCODING |
Para decodificar os arquivos CSV pelo tipo de codificação fornecido. A codificação padrão é UTF-8 |
lineSep |
Qualquer separador de linha de caractere único |
RECORD_DELIMITER |
Para definir o separador de linha que deve ser usado na análise de arquivos. |
pathGlobFilter |
Padrão de arquivo |
PATTERN |
Para definir um padrão para ler arquivos somente com nomes de arquivos que correspondam ao padrão. |
recursiveFileLookup |
Verdadeiro ou falso |
N/A |
Para examinar recursivamente um diretório para ler arquivos. O valor padrão dessa opção é False. |
quote |
Caractere único a ser citado |
FIELD_OPTIONALLY_ENCLOSED_BY |
Para citar campos/colunas que contêm campos em que o delimitador/separador pode fazer parte do valor. Esse caractere Para citar todos os campos quando usado com a opção quoteAll. O valor padrão dessa opção é aspas duplas («). |
nullValue |
Cadeia de caracteres para substituir null |
NULL_IF |
Para substituir os valores nulos pela cadeia de caracteres durante a leitura e gravação do dataframe. |
dateFormat |
Formato de data válido |
DATE_FORMAT |
Para definir uma cadeia de caracteres que indica um formato de data. O formato padrão é yyyy-MM-dd. |
timestampFormat |
Formato de carimbo de data/hora válido |
TIMESTAMP_FORMAT |
Para definir uma cadeia de caracteres que indica um formato de carimbo de data/hora. O formato padrão é yyyy-MM-dd “T’HH:mm:ss. |
escape |
Qualquer caractere único |
ESCAPE |
Para definir um único caractere como caractere de escape para substituir o caractere de escape padrão (\). |
inferSchema |
Verdadeiro ou falso |
INFER_SCHEMA |
Detecta automaticamente o esquema do arquivo |
mergeSchema |
Verdadeiro ou falso |
N/A |
Não é necessário no snowflake, pois isso acontece sempre que o infer_schema determina a estrutura do arquivo parquet |
Para a opção modifiedBefore / modifiedAfter, você pode obter o mesmo resultado no Snowflake usando as colunas de metadados e, em seguida, adicionando um filtro como:
df.filter(METADATA_FILE_LAST_MODIFIED > 'some_date')
.Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1045¶
Mensagem: pyspark.sql.functions.map_values tem uma solução alternativa
Categoria: Aviso.
Descrição¶
Essa função é usada para extrair a lista de valores de uma coluna que contém um mapa/dicionário (chaves/valores).
O problema aparece quando a ferramenta detecta o uso de pyspark.sql.functions.map_values, que tem uma solução alternativa.
Cenário¶
Entrada
Veja a seguir um exemplo de uso do método map_values
.
df = spark.createDataFrame(
[(1, {'Apple': 'Fruit', 'Potato': 'Vegetable'})],
("id", "a_map"))
df.select(map_values("a_map")).show()
Saída
A ferramenta adiciona o EWI SPRKPY1045
indicando que uma solução alternativa pode ser implementada.
df = spark.createDataFrame(
[(1, {'Apple': 'Fruit', 'Potato': 'Vegetable'})],
("id", "a_map"))
#EWI: SPRKPY1045 => pyspark.sql.functions.map_values has a workaround, see documentation for more info
df.select(map_values("a_map")).show()
Correção recomendada
Como solução alternativa, você pode criar um udf para obter os valores de uma coluna. O exemplo a seguir mostra como criar o udf, atribuí-lo a F.map_values
e usá-lo.
from snowflake.snowpark import functions as F
from snowflake.snowpark.types import ArrayType, MapType
map_values_udf=None
def map_values(map):
global map_values_udf
if not map_values_udf:
def _map_values(map: dict)->list:
return list(map.values())
map_values_udf = F.udf(_map_values,return_type=ArrayType(),input_types=[MapType()],name="map_values",is_permanent=False,replace=True)
return map_values_udf(map)
F.map_values = map_values
df.select(map_values(colDict))
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1014¶
Mensagem: pyspark.sql.functions.asinh tem uma solução alternativa
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.functions.asinh, que tem uma solução alternativa.
Cenário¶
Entrada
Nesse exemplo, o pyspark calcula o asinh para um dataframe usando pyspark.sql.functions.asinh.
from pyspark.sql import SparkSession
from pyspark.sql.functions import asinh
spark = SparkSession.builder.getOrCreate()
data = [['V1', 3.0],
['V2', 60.0],
['V3', 14.0],
['V4', 3.1]]
columns = ['Paremeter', 'value']
df = spark.createDataFrame(data, columns)
df_result = df.withColumn("asinh_value", asinh(df["value"]))
Saída
O SMA retorna o EWI SPRKPY1014 sobre a linha em que o asinh é usado, para que você possa identificar onde corrigir.
from snowflake.snowpark import Session
spark = Session.builder.getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":0,"minor":0,"patch":0},"attributes":{"language":"Python"}})
data = [['V1', 3.0],
['V2', 60.0],
['V3', 14.0],
['V4', 3.1]]
columns = ['Paremeter', 'value']
df = spark.createDataFrame(data, columns)
#EWI: SPRKPY1014 => pyspark.sql.functions.asinh has a workaround, see documentation for more info
df_result = df.withColumn("asinh_value", asinh(df["value"]))
Correção recomendada
Não há implementação direta do «asinh», mas, em vez disso, pode-se usar «call_function «, usando «asinh» como o primeiro parâmetro e colName como o segundo.
import snowflake.snowpark as snowpark
from snowflake.snowpark import Session
from snowflake.snowpark.functions import call_function, col
spark = Session.builder.getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":0,"minor":0,"patch":0},"attributes":{"language":"Python"}})
data = [['V1', 3.0],
['V2', 60.0],
['V3', 14.0],
['V4', 3.1]]
columns = ['Paremeter', 'value']
df = spark.createDataFrame(data, columns)
df_result = df.select(call_function('asinh', col('value')))
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1004¶
Message : A tabela de símbolos não pôde ser carregada.
Category : Erro de análise.
Descrição¶
Esse problema aparece quando há um erro inesperado no processo de execução da ferramenta. Como a tabela de símbolos não pode ser carregada, a ferramenta não pode iniciar o processo de avaliação ou conversão.
Recomendações adicionais ¶
É improvável que isso seja um erro no próprio código-fonte, mas sim um erro na forma como a ferramenta processa o código-fonte. A melhor solução seria entrar em contato com a equipe de suporte do SMA. Você pode enviar um e-mail para sma-support@snowflake.com.
Para obter mais suporte, você pode enviar um e-mail para sma-support@snowflake.com ou publicar um problema no SMA.
SPRKPY1055¶
Mensagem: o valor da chave pyspark.sql.readwriter.DataFrameReader.option não é suportado.
Categoria: Aviso.
Descrição¶
Esse problema aparece quando o valor da chave pyspark.sql.readwriter.DataFrameReader.option
não é suportado pelo SnowFlake.
A ferramenta analisa os parâmetros de chamada de opção e, dependendo do método (CSV ou JSON ou PARQUET), o valor da chave pode ter ou não um equivalente no Snowpark. Se todos os parâmetros tiverem um equivalente, a ferramenta não adicionará o EWI e substituirá o valor da chave pelo seu equivalente; caso contrário, a ferramenta adicionará o EWI.
Lista de equivalências:
Equivalências para CSV:
Chaves de opção do Spark |
Equivalências do Snowpark |
---|---|
sep |
FIELD_DELIMITER |
header |
PARSE_HEADER |
lineSep |
RECORD_DELIMITER |
pathGlobFilter |
PATTERN |
quote |
FIELD_OPTIONALLY_ENCLOSED_BY |
nullValue |
NULL_IF |
dateFormat |
DATE_FORMAT |
timestampFormat |
TIMESTAMP_FORMAT |
inferSchema |
INFER_SCHEMA |
delimiter |
FIELD_DELIMITER |
Equivalências para JSON:
Chaves de opção do Spark |
Equivalências do Snowpark |
---|---|
dateFormat |
DATE_FORMAT |
timestampFormat |
TIMESTAMP_FORMAT |
pathGlobFilter |
PATTERN |
Equivalências para PARQUET:
Chaves de opção do Spark |
Equivalências do Snowpark |
---|---|
pathGlobFilter |
PATTERN |
Qualquer outra opção de chave que não esteja em uma das tabelas acima não é compatível ou não tem um equivalente no Snowpark. Se esse for o caso, a ferramenta adiciona o EWI com as informações do parâmetro e o remove da cadeia.
Cenários¶
Os cenários abaixo se aplicam a CSV, JSON e PARQUET.
Há alguns cenários que dependem do valor da chave usada no método option
.
Cenário 1¶
Entrada
Abaixo está um exemplo de uma chamada option
usando uma chave equivalente
.
from pyspark.sql import SparkSession
spark = SparkSession.builder.getOrCreate()
## CSV example:
spark.read.option("header", True).csv(csv_file_path)
## Json example:
spark.read.option("dateFormat", "dd-MM-yyyy").json(json_file_path)
## Parquet example:
spark.read.option("pathGlobFilter", "*.parquet").parquet(parquet_file_path)
Saída
A ferramenta transforma a chave com o equivalente correto.
from snowflake.snowpark import Session
spark = Session.builder.getOrCreate()
## CSV example:
spark.read.option("PARSE_HEADER", True).csv(csv_file_path)
## Json example:
spark.read.option("DATE_FORMAT", "dd-MM-yyyy").json(json_file_path)
## Parquet example:
spark.read.option("PATTERN", "*.parquet").parquet(parquet_file_path)
Correção recomendada
Como a ferramenta transforma o valor da chave, não há necessidade de correção.
Cenário 2¶
Entrada
Abaixo está um exemplo de uma chamada option
usando uma chave não equivalente
.
from pyspark.sql import SparkSession
spark = SparkSession.builder.getOrCreate()
## CSV example:
spark.read.option("anotherKeyValue", "myVal").csv(csv_file_path)
## Json example:
spark.read.option("anotherKeyValue", "myVal").json(json_file_path)
## Parquet example:
spark.read.option("anotherKeyValue", "myVal").parquet(parquet_file_path)
Saída
A ferramenta adiciona o EWI SPRKPY1055
indicando que a chave não é compatível e remove a chamada option
.
from snowflake.snowpark import Session
spark = Session.builder.getOrCreate()
## CSV example:
#EWI: SPRKPY1055 => pyspark.sql.readwriter.DataFrameReader.option with key value "anotherKeyValue" is not supported.
spark.read.csv(csv_file_path)
## Json example:
#EWI: SPRKPY1055 => pyspark.sql.readwriter.DataFrameReader.option with key value "anotherKeyValue" is not supported.
spark.read.json(json_file_path)
## Parquet example:
#EWI: SPRKPY1055 => pyspark.sql.readwriter.DataFrameReader.option with key value "anotherKeyValue" is not supported.
spark.read.parquet(parquet_file_path)
Correção recomendada
Recomenda-se que verifique o comportamento após a transformação.
Recomendações adicionais¶
Quando houver parâmetros não equivalentes, é recomendável verificar o comportamento após a transformação.
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1061¶
Mensagem: O Snowpark não é compatível com as funções unix_timestamp
Categoria: Aviso
Descrição¶
No Snowpark, o primeiro parâmetro é obrigatório; o problema aparece quando a ferramenta detecta o uso de pyspark.sql.functions.unix_timestamp sem parâmetros.
Cenário¶
Entrada
Abaixo, um exemplo que chama o método unix_timestamp
sem parâmetros.
data = [["2015-04-08", "10"],["2015-04-10", "15"]]
df = spark.createDataFrame(data, ['dt', 'val'])
df.select(unix_timestamp()).show()
Saída
A assinatura do Snowpark para essa função unix_timestamp(e: ColumnOrName, fmt: Optional["Column"] = None)
, como você pode notar, o primeiro parâmetro é obrigatório.
A ferramenta adiciona este EWI SPRKPY1061
para que saiba que a função unix_timestamp sem parâmetros não é compatível com o Snowpark.
data = [["2015-04-08", "10"],["2015-04-10", "15"]]
df = spark.createDataFrame(data, ['dt', 'val'])
#EWI: SPRKPY1061 => Snowpark does not support unix_timestamp functions with no parameters. See documentation for more info.
df.select(unix_timestamp()).show()
Correção recomendada
Como solução alternativa, você pode adicionar pelo menos o nome ou a coluna da cadeia de caracteres de carimbo de data/hora.
data = [["2015-04-08", "10"],["2015-04-10", "15"]]
df = spark.createDataFrame(data, ["dt", "val"])
df.select(unix_timestamp("dt")).show()
Recomendações adicionais¶
Você também pode adicionar current_timestamp() como o primeiro parâmetro.
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1030¶
Aviso
Este código de problema está obsoleto
Mensagem: pyspark.sql.session.SparkSession.Builder.appName tem uma solução alternativa, consulte a documentação para obter mais informações
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.sql.session.SparkSession.Builder.appName, que tem uma solução alternativa.
Cenário¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.session.SparkSession.Builder.appName
que gera esse EWI. Neste exemplo, a função appName
é usada para definir MyApp como o nome do aplicativo.
session = SparkSession.builder.appName("MyApp").getOrCreate()
Saída
O SMA adiciona o EWI SPRKPY1030
ao código de saída para que você saiba que essa função não é diretamente compatível com o Snowpark, mas tem uma solução alternativa.
#EWI: SPRKPY1030 => pyspark.sql.session.SparkSession.Builder.appName has a workaround, see documentation for more info
session = Session.builder.appName("MyApp").getOrCreate()
Correção recomendada
Como solução alternativa, você pode importar o pacote snowpark_extensions, que fornece uma extensão para a função appName
.
import snowpark_extensions
session = SessionBuilder.appName("MyApp").getOrCreate()
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1010¶
Mensagem: pyspark.sql.dataframe.DataFrame.checkpoint tem uma solução alternativa
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.dataframe.DataFrame.checkpoint que tem uma solução alternativa.
Cenário¶
Entrada
Em PySpark, os pontos de controle são usados para truncar o plano lógico de um dataframe, para evitar o crescimento de um plano lógico.
import tempfile
from pyspark.sql import SparkSession
spark = SparkSession.builder.getOrCreate()
data = [['Q1', 300000],
['Q2', 60000],
['Q3', 500002],
['Q4', 130000]]
columns = ['Quarter', 'Score']
df = spark.createDataFrame(data, columns)
with tempfile.TemporaryDirectory() as d:
spark.sparkContext.setCheckpointDir("/tmp/bb")
df.checkpoint(False)
Saída
O SMA retorna o EWI SPRKPY1010 sobre a linha em que approxQuantile é usado, para que você possa identificar onde corrigir. Observe que isso também marca o diretório setCheckpointDir como sem suporte, mas não é necessário um diretório com ponto de verificação para a correção.
import tempfile
from snowflake.snowpark import Session
spark = Session.builder.getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":0,"minor":0,"patch":0},"attributes":{"language":"Python"}})
data = [['Q1', 300000],
['Q2', 60000],
['Q3', 500002],
['Q4', 130000]]
columns = ['Quarter', 'Score']
df = spark.createDataFrame(data, columns)
with tempfile.TemporaryDirectory() as d:
#EWI: SPRKPY1002 => pyspark.context.SparkContext.setCheckpointDir is not supported
spark.setCheckpointDir("/tmp/bb")
#EWI: SPRKPY1010 => pyspark.sql.dataframe.DataFrame.checkpoint has a workaround, see documentation for more info
df.checkpoint(False)
Correção recomendada
O Snowpark elimina a necessidade de pontos de verificação explícitos: isso ocorre porque o Snowpark trabalha com operações baseadas em SQLque são otimizadas pelo mecanismo de otimização de consultas do Snowflake, eliminando a necessidade de cálculos não correspondidos ou planos lógicos que ficam fora de controle.
No entanto, pode haver cenários em que você precise manter o resultado de um cálculo em um dataframe. Nesses cenários, você pode salvar a materialização dos resultados gravando o dataframe em uma tabela Snowflake ou em uma tabela temporária Snowflake.
Com o uso de uma tabela permanente, o resultado computado pode ser acessado a qualquer momento, mesmo após o término da sessão.
from snowflake.snowpark import Session
spark = Session.builder.getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":0,"minor":0,"patch":0},"attributes":{"language":"Python"}})
data = [['Q1', 300000],
['Q2', 60000],
['Q3', 500002],
['Q4', 130000]]
columns = ['Quarter', 'Score']
df = spark.createDataFrame(data, columns)
df.write.save_as_table("my_table", table_type="temporary") # Save the dataframe into Snowflake table "my_table".
df2 = Session.table("my_table") # Now I can access the stored result quering the table "my_table"
Uma solução alternativa, o uso de uma tabela temporária, tem a vantagem de que a tabela é excluída após o término da sessão:
from snowflake.snowpark import Session
spark = Session.builder.getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":0,"minor":0,"patch":0},"attributes":{"language":"Python"}})
data = [['Q1', 300000],
['Q2', 60000],
['Q3', 500002],
['Q4', 130000]]
columns = ['Quarter', 'Score']
df = spark.createDataFrame(data, columns)
df.write.save_as_table("my_temp_table", table_type="temporary") # Save the dataframe into Snowflake table "my_temp_table".
df2 = Session.table("my_temp_table") # Now I can access the stored result quering the table "my_temp_table"
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1101¶
Categoria¶
Erro de análise.
Descrição¶
Quando a ferramenta reconhece um erro de análise, ela tenta se recuperar dele e continua o processo na próxima linha. Nesses casos, ele mostra o erro e os comentários sobre a linha.
Este exemplo mostra como é tratado um erro de incompatibilidade entre espaços e tabulações.
Código de entrada
def foo():
x = 5 # Spaces
y = 6 # Tab
def foo2():
x=6
y=7
Código de saída
def foo():
x = 5 # Spaces
## EWI: SPRKPY1101 => Unrecognized or invalid CODE STATEMENT @(3, 2). Last valid token was '5' @(2, 9), failed token 'y' @(3, 2)
## y = 6 # Tab
def foo2():
x=6
y=7
Recomendações¶
Tente corrigir a linha comentada.
Para obter mais suporte, envie-nos um e-mail para sma-support@snowflake.com. Se tiver um contrato de suporte com a Snowflake, entre em contato com seu engenheiro de vendas, que poderá direcionar suas necessidades de suporte.
SPRKPY1041¶
Aviso
Esse código de problema foi depreciado desde o Spark Conversion Core Version 2.9.0
Mensagem: pyspark.sql.functions.explode_outer tem uma solução alternativa
Categoria: Aviso
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.functions.explode_outer, que tem uma solução alternativa.
Cenário¶
Entrada
O exemplo mostra o uso do método explode_outer em uma chamada de seleção.
df = spark.createDataFrame(
[(1, ["foo", "bar"], {"x": 1.0}),
(2, [], {}),
(3, None, None)],
("id", "an_array", "a_map")
)
df.select("id", "an_array", explode_outer("a_map")).show()
Saída
A ferramenta adiciona o EWI SPRKPY1041
indicando que uma solução alternativa pode ser implementada.
df = spark.createDataFrame(
[(1, ["foo", "bar"], {"x": 1.0}),
(2, [], {}),
(3, None, None)],
("id", "an_array", "a_map")
)
#EWI: SPRKPY1041 => pyspark.sql.functions.explode_outer has a workaround, see documentation for more info
df.select("id", "an_array", explode_outer("a_map")).show()
Correção recomendada
Como solução alternativa, você senhor pode importar o pacote snowpark_extensions, que contém um auxiliar para a função explode_outer
.
import snowpark_extensions
df = spark.createDataFrame(
[(1, ["foo", "bar"], {"x": 1.0}),
(2, [], {}),
(3, None, None)],
("id", "an_array", "a_map")
)
df.select("id", "an_array", explode_outer("a_map")).show()
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1075¶
Categoria
Aviso.
Descrição¶
O parse_json não aplica validação de esquema; se precisar filtrar/validar com base no esquema, talvez seja necessário introduzir alguma lógica.
Exemplo¶
Entrada
df.select(from_json(df.value, Schema))
df.select(from_json(schema=Schema, col=df.value))
df.select(from_json(df.value, Schema, option))
Saída
#EWI: SPRKPY1075 => The parse_json does not apply schema validation, if you need to filter/validate based on schema you might need to introduce some logic.
df.select(parse_json(df.value))
#EWI: SPRKPY1075 => The parse_json does not apply schema validation, if you need to filter/validate based on schema you might need to introduce some logic.
df.select(parse_json(df.value))
#EWI: SPRKPY1075 => The parse_json does not apply schema validation, if you need to filter/validate based on schema you might need to introduce some logic.
df.select(parse_json(df.value))
Para a função from_json, o esquema não é realmente passado para inferência, mas é usado para validação. Veja estes exemplos:
data = [
('{"name": "John", "age": 30, "city": "New York"}',),
('{"name": "Jane", "age": "25", "city": "San Francisco"}',)
]
df = spark.createDataFrame(data, ["json_str"])
Exemplo 1: Aplicar tipos de dados e alterar nomes de colunas:
## Parse JSON column with schema
parsed_df = df.withColumn("parsed_json", from_json(col("json_str"), schema))
parsed_df.show(truncate=False)
## +------------------------------------------------------+---------------------------+
## |json_str |parsed_json |
## +------------------------------------------------------+---------------------------+
## |{"name": "John", "age": 30, "city": "New York"} |{John, 30, New York} |
## |{"name": "Jane", "age": "25", "city": "San Francisco"}|{Jane, null, San Francisco}|
## +------------------------------------------------------+---------------------------+
## notice that values outside of the schema were dropped and columns not matched are returned as null
Exemplo 2: Selecionar colunas específicas:
## Define a schema with only the columns we want to use
partial_schema = StructType([
StructField("name", StringType(), True),
StructField("city", StringType(), True)
])
## Parse JSON column with partial schema
partial_df = df.withColumn("parsed_json", from_json(col("json_str"), partial_schema))
partial_df.show(truncate=False)
## +------------------------------------------------------+---------------------+
## |json_str |parsed_json |
## +------------------------------------------------------+---------------------+
## |{"name": "John", "age": 30, "city": "New York"} |{John, New York} |
## |{"name": "Jane", "age": "25", "city": "San Francisco"}|{Jane, San Francisco}|
## +------------------------------------------------------+---------------------+
## there is also an automatic filtering
Recomendações¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com. Se tiver um contrato de suporte com a Snowflake, entre em contato com seu engenheiro de vendas para que ele possa direcionar suas necessidades de suporte.
SPRKPY1024¶
Mensagem: pyspark.sql.functions.log2 tem uma solução alternativa, consulte a documentação para obter mais informações
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.sql.functions.log2, que tem uma solução alternativa.
Cenário¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.functions.log2
que gera esse EWI. Neste exemplo, a função log2
é usada para calcular o logaritmo de base 2 da coluna value.
df = spark.createDataFrame([(1,), (2,), (4,), (8,), (16,)], ["value"])
df_with_log2 = df.withColumn("log2_value", log2(df["value"]))
Saída
O SMA adiciona o EWI SPRKPY1024
ao código de saída para que você saiba que essa função não é diretamente compatível com o Snowpark, mas tem uma solução alternativa.
df = spark.createDataFrame([(1,), (2,), (4,), (8,), (16,)], ["value"])
#EWI: SPRKPY1024 => pyspark.sql.functions.log2 has a workaround, see documentation for more info
df_with_log2 = df.withColumn("log2_value", log2(df["value"]))
Correção recomendada
Como solução alternativa, você pode usar a função snowflake.snowpark.functions.log passando o valor literal 2
como base.
df = session.createDataFrame([(1,), (2,), (4,), (8,), (16,)], ["value"])
df_with_log2 = df.withColumn("log2_value", log(2, df["value"]))
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1086¶
Mensagem: pyspark.ml.linalg.VectorUDT não é compatível.
Categoria: Aviso
Descrição¶
O pyspark.ml.linalg.VectorUDT não é compatível.
Cenário¶
Código de entrada
VectorUDT é um tipo de dados para representar colunas de vetores em um DataFrame.
data = [
(1, Vectors.dense([10.0, 20.0])),
(2, Vectors.dense([25.0, 30.0])),
(3, Vectors.dense([50.0, 60.0]))
]
schema = StructType([
StructField("Id", IntegerType(), True),
StructField("VectorCol", VectorUDT(), True),
])
df = SparkSession.createDataFrame(data, schema=schema)
Código de saída
A ferramenta adiciona esse EWI SPRKPY1086
no código de saída para que você saiba que essa função não é compatível com o Snowpark.
data = [
(1, Vectors.dense([10.0, 20.0])),
(2, Vectors.dense([25.0, 30.0])),
(3, Vectors.dense([50.0, 60.0]))
]
#EWI: SPRKPY1086 => The pyspark.ml.linalg.VectorUDT function is not supported.
schema = StructType([
StructField("Id", IntegerType(), True),
StructField("VectorCol", VectorUDT(), True),
])
df = spark.createDataFrame(data, schema=schema)
Correção recomendada
O pyspark.ml.linalg.VectorUDT não tem uma correção recomendada.
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1034¶
Aviso
Este código de problema está obsoleto
Mensagem: pyspark.sql.functions.desc tem uma solução alternativa, consulte a documentação para obter mais informações
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.sql.functions.desc, que tem uma solução alternativa.
Cenários¶
A função pyspark.sql.functions.desc
recebe como parâmetro um objeto de coluna ou o nome da coluna como uma cadeia de caracteres. Ambos os cenários não são compatíveis com o Snowpark, portanto, este EWI é gerado.
Cenário 1¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.functions.desc
que recebe um objeto de coluna como parâmetro.
df.orderBy(desc(col))
Saída
O SMA adiciona o EWI SPRKPY1034
ao código de saída para que você saiba que a função desc
com um parâmetro de objeto de coluna não é diretamente compatível com o Snowpark, mas tem uma solução alternativa.
#EWI: SPRKPY1034 => pyspark.sql.functions.desc has a workaround, see documentation for more info
df.orderBy(desc(col))
Correção recomendada
Como solução alternativa, o senhor pode chamar a função snowflake.snowpark.Column.desc a partir do parâmetro da coluna.
df.orderBy(col.desc())
Cenário 2¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.functions.desc
que usa o nome da coluna como parâmetro.
df.orderBy(desc("colName"))
Saída
O SMA adiciona o EWI SPRKPY1034
ao código de saída para que você saiba que a função desc
com um parâmetro de nome de coluna não é diretamente compatível com o Snowpark, mas tem uma solução alternativa.
#EWI: SPRKPY1034 => pyspark.sql.functions.desc has a workaround, see documentation for more info
df.orderBy(desc("colName"))
Correção recomendada
Como solução alternativa, você pode converter o parâmetro string em um objeto de coluna usando a função snowflake.snowpark.functions.col e, em seguida, chamar a função snowflake.snowpark.Column.desc.
df.orderBy(col("colName").desc())
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1065¶
Mensagem: O pyspark.context.SparkContext.broadcast não se aplica, pois o snowflake usa o mecanismo data-clustering para computar os dados.
Categoria: Aviso
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso do elemento pyspark.context.SparkContext.broadcast, que não é necessário devido ao uso de data-clustering do Snowflake.
Código de entrada
Neste exemplo, é criada uma variável de transmissão. Essas variáveis permitem que os dados sejam compartilhados de forma mais eficiente por todos os nós.
sc = SparkContext(conf=conf_spark)
mapping = {1: 10001, 2: 10002}
bc = sc.broadcast(mapping)
Código de saída
O SMA adiciona uma mensagem EWI indicando que a transmissão não é necessária.
sc = conf_spark
mapping = {1: 10001, 2: 10002}
#EWI: SPRKPY1065 => The element does not apply since snowflake use data-clustering mechanism to compute the data.
bc = sc.broadcast(mapping)
Correção recomendada
Remova todos os usos de pyspark.context.SparkContext.broadcast.
sc = conf_spark
mapping = {1: 10001, 2: 10002}
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1051¶
Aviso
Esse código de problema foi depreciado desde o Spark Conversion Core Version 2.4.0
Mensagem: pyspark.sql.session.SparkSession.Builder.master tem uma solução alternativa
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.session.SparkSession.Builder.master, que tem uma solução alternativa.
Cenário¶
Entrada
Abaixo está um exemplo do uso do método builder.master
para definir o Spark Master URL para se conectar ao local usando 1 núcleo.
spark = SparkSession.builder.master("local[1]")
Saída
A ferramenta adiciona o EWI SPRKPY1051
indicando que uma solução alternativa pode ser implementada.
#EWI: SPRKPY1051 => pyspark.sql.session.SparkSession.Builder.master has a workaround, see documentation for more info
spark = Session.builder.master("local[1]")
Correção recomendada
pyspark.sql.session.SparkSession.Builder.master
é usado para configurar um Spark Cluster. O Snowpark não usa Spark Clusters, então você pode remover ou comentar o código.
## spark = Session.builder.master("local[1]")
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1000¶
Mensagem: A versão do núcleo de projeto spark-core de origem é xx.xx:xx.x.x, a versão do spark-core suportada pelo snowpark é 2.12:3.1.2, portanto, pode haver diferenças funcionais entre os mapeamentos existentes.
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a versão do Pyspark do seu código-fonte não é compatível. Isso significa que pode haver diferenças funcionais entre os mapeamentos existentes.
Recomendações adicionais¶
A versão do pyspark verificada pelo SMA para compatibilidade com o Snowpark é de 2.12 a 3.1.2. Se estiver usando uma versão fora desse intervalo, a ferramenta poderá produzir resultados inconsistentes. Você pode alterar a versão do código-fonte que está verificando.
Para obter mais suporte, você pode enviar um e-mail para sma-support@snowflake.com ou publicar um problema no SMA.
SPRKPY1081¶
Esse código de problema foi depreciado desde o Spark Conversion Core 4.12.0
Mensagem: pyspark.sql.readwriter.DataFrameWriter.partitionBy tem uma solução alternativa.
Categoria: Aviso
Descrição¶
Não há suporte para a função Pyspark.sql.readwriter.DataFrameWriter.partitionBy. A solução alternativa é usar o copy_into_location do Snowpark. Consulte a documentação para obter mais informações.
Cenário¶
Entrada
Esse código criará um diretório separado para cada valor exclusivo na coluna FIRST_NAME
. Os dados são os mesmos, mas serão armazenados em diretórios diferentes com base na coluna.
df = session.createDataFrame([["John", "Berry"], ["Rick", "Berry"], ["Anthony", "Davis"]], schema = ["FIRST_NAME", "LAST_NAME"])
df.write.partitionBy("FIRST_NAME").csv("/home/data")
Esse código criará um diretório separado para cada valor exclusivo na coluna FIRST_NAME
. Os dados são os mesmos, mas serão armazenados em diretórios diferentes com base na coluna.
Código de saída
df = session.createDataFrame([["John", "Berry"], ["Rick", "Berry"], ["Anthony", "Davis"]], schema = ["FIRST_NAME", "LAST_NAME"])
#EWI: SPRKPY1081 => The partitionBy function is not supported, but you can instead use copy_into_location as workaround. See the documentation for more info.
df.write.partitionBy("FIRST_NAME").csv("/home/data", format_type_options = dict(compression = "None"))
Correção recomendada
No Snowpark, copy_into_location tem um parâmetro partition_by que você pode usar em vez da função partitionBy, mas isso exigirá alguns ajustes manuais, conforme mostrado no exemplo a seguir:
Código do Spark:
df = session.createDataFrame([["John", "Berry"], ["Rick", "Berry"], ["Anthony", "Davis"]], schema = ["FIRST_NAME", "LAST_NAME"])
df.write.partitionBy("FIRST_NAME").csv("/home/data")
O código do Snowpark foi ajustado manualmente:
df = session.createDataFrame([["John", "Berry"], ["Rick", "Berry"], ["Anthony", "Davis"]], schema = ["FIRST_NAME", "LAST_NAME"])
df.write.copy_into_location(location=temp_stage, partition_by=col("FIRST_NAME"), file_format_type="csv", format_type_options={"COMPRESSION": "NONE"}, header=True)
copy_into_location tem os seguintes parâmetros
location: O local do Snowpark só aceita locais de nuvem que usam um estágio do snowflake.
partition_by: Pode ser um nome de coluna ou uma expressão SQL, portanto, você precisará convertê-la em uma coluna ou em uma expressão SQL, usando col ou sql_expr.
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1072¶
Mensagem: O uso do StorageLevel não é obrigatório no Snowpark.
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta encontra o uso da classe StorageLevel que funciona como «sinalizadores» para definir o nível de armazenamento. Como o Snowflake controla o armazenamento, o uso dessa função não é necessário.
Recomendações adicionais¶
Remover todos os usos dessa função.
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1023¶
Mensagem: pyspark.sql.functions.log1p tem uma solução alternativa, consulte a documentação para obter mais informações
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.sql.functions.log1p, que tem uma solução alternativa.
Cenário¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.functions.log1p
que gera esse EWI. Neste exemplo, a função log1p
é usada para calcular o logaritmo natural da coluna value.
df = spark.createDataFrame([(0,), (1,), (10,), (100,)], ["value"])
df_with_log1p = df.withColumn("log1p_value", log1p(df["value"]))
Saída
O SMA adiciona o EWI SPRKPY1023
ao código de saída para que você saiba que essa função não é diretamente compatível com o Snowpark, mas tem uma solução alternativa.
df = spark.createDataFrame([(0,), (1,), (10,), (100,)], ["value"])
#EWI: SPRKPY1023 => pyspark.sql.functions.log1p has a workaround, see documentation for more info
df_with_log1p = df.withColumn("log1p_value", log1p(df["value"]))
Correção recomendada
Como solução alternativa, você pode usar a função call_function passando a cadeia de caracteres ln
como primeiro argumento e adicionando 1
ao segundo argumento.
df = spark.createDataFrame([(0,), (1,), (10,), (100,)], ["value"])
df_with_log1p = df.withColumn("log1p_value", call_function("ln", lit(1) + df["value"]))
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1017¶
Aviso
Esse código de problema foi depreciado desde o Spark Conversion Core Version 4.8.0
pyspark.sql.functions.date_add tem uma solução alternativa
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.functions.date_add, que tem uma solução alternativa.
Cenário¶
Entrada
Neste exemplo, usamos date_add para calcular a data 5 dias após a data atual para o dataframe df.
col = df.select(date_add(df.colName, 5))
Saída
SMA retorna o EWI SPRKPY1017 sobre a linha em que date_add é usado, para que você possa identificar onde corrigir.
#EWI: SPRKPY1017 => pyspark.sql.functions.date_add has a workaround, see documentation for more info
col = df.select(date_add(df.colName, 5))
Correção recomendada
Importe snowflake.snowpark.functions, que contém uma implementação para a função date_add (e o alias dateAdd).
from snowflake.snowpark.functions import date_add
col = df.select(date_add(df.dt, 1))
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1046¶
Aviso
Esse código de problema foi descontinuado desde o Spark Conversion Core Version 2.1.22
Mensagem: pyspark.sql.functions.monotonically_increasing_id tem uma solução alternativa
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.functions.monotonically_increasing_id, que tem uma solução alternativa.
Cenário¶
Entrada
Veja a seguir um exemplo de uso do método monotonically_increasing_id
.
from pyspark.sql import functions as F
spark.range(0, 10, 1, 2).select(F.monotonically_increasing_id()).show()
Saída
A ferramenta adiciona o EWI SPRKPY1046
indicando que uma solução alternativa pode ser implementada.
from pyspark.sql import functions as F
#EWI: SPRKPY1046 => pyspark.sql.functions.monotonically_increasing_id has a workaround, see documentation for more info
spark.range(0, 10, 1, 2).select(F.monotonically_increasing_id()).show()
Correção recomendada
Atualize a versão da ferramenta.
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1056¶
Aviso
Este código de problema está obsoleto
Mensagem: pyspark.sql.readwriter.DataFrameReader.option argument _ <argument_name> _ não é um literal e não pode ser avaliado
Categoria: Aviso
Descrição¶
Esse problema aparece quando a chave ou o valor do argumento da função pyspark.sql.readwriter.DataFrameReader.option não é um valor literal (por exemplo, uma variável). O SMA faz uma análise estática do seu código-fonte e, portanto, não é possível avaliar o conteúdo do argumento.
Cenário¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.readwriter.DataFrameReader.option
que gera esse EWI.
my_value = ...
my_option = ...
df1 = spark.read.option("dateFormat", my_value).format("csv").load('filename.csv')
df2 = spark.read.option(my_option, "false").format("csv").load('filename.csv')
Saída
O SMA adiciona o EWI SPRKPY1056
ao código de saída para que você saiba que o argumento dessa função não é um valor literal e, portanto, não pode ser avaliado pelo SMA.
my_value = ...
my_option = ...
#EWI: SPRKPY1056 => pyspark.sql.readwriter.DataFrameReader.option argument "dateFormat" is not a literal and can't be evaluated
df1 = spark.read.option("dateFormat", my_value).format("csv").load('filename.csv')
#EWI: SPRKPY1056 => pyspark.sql.readwriter.DataFrameReader.option argument key is not a literal and can't be evaluated
df2 = spark.read.option(my_option, "false").format("csv").load('filename.csv')
Correção recomendada
Mesmo que o SMA não tenha conseguido avaliar o argumento, isso não significa que ele não seja apoiado pelo Snowpark. Certifique-se de que o valor do argumento seja válido e equivalente no Snowpark, verificando a documentação.
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1007¶
Aviso
Esse código de problema foi depreciado desde o Spark Conversion Core Version 4.8.0
Message : pyspark.sql.context.SQLContext não é necessário
Category : Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso do pyspark.sql.context.SQLContext, que não é necessário.
Cenário¶
Entrada
Aqui temos um exemplo com diferentes sobrecargas de SparkContext.
from pyspark import SQLContext
my_sc1 = SQLContext(myMaster, myAppName, mySparkHome, myPyFiles, myEnvironment, myBatctSize, mySerializer, my_conf1)
my_sc2 = SQLContext(conf=my_conf2)
my_sc3 = SQLContext()
Saída
O código de saída comentou a linha do pyspark.SQLContext, e substitui os cenários por uma referência a uma configuração. Observe que as variáveis my_sc1 e my_sc2 que contêm propriedades do Spark podem não ser necessárias ou terão de ser adaptadas para corrigir o código.
#EWI: SPRKPY1007 => pyspark.sql.context.SQLContext is not required
#from pyspark import SQLContext
pass
#EWI: SPRKPY1007 => pyspark.sql.context.SQLContext is not required
sql_context1 = my_sc1
#EWI: SPRKPY1007 => pyspark.sql.context.SQLContext is not required
sql_context2 = my_sc2
Recomendações adicionais¶
Esse é um parâmetro desnecessário e é removido com um comentário de aviso inserido no código-fonte. Não deve haver nenhuma ação por parte do usuário.
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1033¶
Aviso
Este código de problema está obsoleto
Mensagem: pyspark.sql.functions.asc tem uma solução alternativa, consulte a documentação para obter mais informações
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.sql.functions.asc, que tem uma solução alternativa.
Cenários¶
A função pyspark.sql.functions.asc
recebe como parâmetro um objeto de coluna ou o nome da coluna como uma cadeia de caracteres. Ambos os cenários não são compatíveis com o Snowpark, portanto, este EWI é gerado.
Cenário 1¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.functions.asc
que recebe um objeto de coluna como parâmetro.
df.orderBy(asc(col))
Saída
O SMA adiciona o EWI SPRKPY1033
ao código de saída para que você saiba que a função asc
com um parâmetro de objeto de coluna não é diretamente compatível com o Snowpark, mas tem uma solução alternativa.
#EWI: SPRKPY1033 => pyspark.sql.functions.asc has a workaround, see documentation for more info
df.orderBy(asc(col))
Correção recomendada
Como solução alternativa, você pode chamar a função snowflake.snowpark.Column.asc a partir do parâmetro column.
df.orderBy(col.asc())
Cenário 2¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.functions.asc
que recebe o nome da coluna como parâmetro.
df.orderBy(asc("colName"))
Saída
O SMA adiciona o EWI SPRKPY1033
ao código de saída para que você saiba que a função asc
com um parâmetro de nome de coluna não é diretamente compatível com o Snowpark, mas tem uma solução alternativa.
#EWI: SPRKPY1033 => pyspark.sql.functions.asc has a workaround, see documentation for more info
df.orderBy(asc("colName"))
Correção recomendada
Como solução alternativa, você pode converter o parâmetro string em um objeto de coluna usando a função snowflake.snowpark.functions.col e, em seguida, chamar a função snowflake.snowpark.Column.asc.
df.orderBy(col("colName").asc())
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1062¶
Mensagem: O Snowpark não é compatível com GroupedData.pivot sem o parâmetro «values».
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.sql.group.GroupedData.pivot sem o parâmetro «values» (a lista de valores sobre os quais pivotar).
No momento, a função de pivô do Snowpark Python exige que você especifique explicitamente a lista de valores distintos sobre os quais fazer o pivô.
Cenários¶
Cenário 1¶
Entrada
O SMA detecta uma expressão que corresponde ao padrão dataFrame.groupBy("columnX").pivot("columnY")
e o pivô não tem o parâmetro values.
df.groupBy("date").pivot("category").sum("amount")
Saída
O SMA adiciona uma mensagem EWI indicando que não há suporte para a função de pivô sem o parâmetro «values».
Além disso, ele adicionará como segundo parâmetro da função de pivô uma compreensão de lista que calcula a lista de valores que serão convertidos em colunas. Lembre-se de que essa operação não é eficiente para grandes conjuntos de dados, e é aconselhável indicar os valores explicitamente.
#EWI: SPRKPY1062 => pyspark.sql.group.GroupedData.pivot without parameter 'values' is not supported. See documentation for more info.
df.groupBy("date").pivot("category", [v[0] for v in df.select("category").distinct().limit(10000).collect()]]).sum("amount")
Correção recomendada
Para esse cenário, o SMA adiciona um segundo parâmetro da função de pivô, uma compreensão de lista que calcula a lista de valores que serão convertidos em colunas, mas você pode usar uma lista de valores distintos para pivotar, como segue:
df = spark.createDataFrame([
Row(category="Client_ID", date=2012, amount=10000),
Row(category="Client_name", date=2012, amount=20000)
])
df.groupBy("date").pivot("category", ["dotNET", "Java"]).sum("amount")
Cenário 2¶
Entrada
O SMA não conseguiu detectar uma expressão que corresponda ao padrão dataFrame.groupBy("columnX").pivot("columnY")
e o pivô não tem o parâmetro values.
df1.union(df2).groupBy("date").pivot("category").sum("amount")
Saída
O SMA adiciona uma mensagem EWI indicando que não há suporte para a função de pivô sem o parâmetro «values».
#EWI: SPRKPY1062 => pyspark.sql.group.GroupedData.pivot without parameter 'values' is not supported. See documentation for more info.
df1.union(df2).groupBy("date").pivot("category").sum("amount")
Correção recomendada
Adicione uma lista de valores distintos para fazer o pivô, como segue:
df = spark.createDataFrame([
Row(course="dotNET", year=2012, earnings=10000),
Row(course="Java", year=2012, earnings=20000)
])
df.groupBy("year").pivot("course", ["dotNET", "Java"]).sum("earnings").show()
Recomendações adicionais¶
O cálculo da lista de valores distintos para pivotar não é uma operação eficiente em grandes conjuntos de dados e pode se tornar uma chamada de bloqueio. Considere a possibilidade de indicar explicitamente a lista de valores distintos para dinamizar.
Se não quiser especificar explicitamente a lista de valores distintos para pivotar (o que não é aconselhável), você pode adicionar o seguinte código como o segundo argumento da função pivot para inferir os valores em tempo de execução*
[v[0] for v in <df>.select(<column>).distinct().limit(<count>).collect()]]
*_ Substitua _ <df>
pelo correspondente DataFrame, pela coluna a ser dinamizada e pelo número de linhas a serem selecionadas.
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1042¶
Mensagem: pyspark.sql.functions.posexplode tem uma solução alternativa
Categoria: Aviso
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.functions.posexplode, que tem uma solução alternativa.
Cenários¶
Há alguns cenários com os quais esse método pode lidar, dependendo do tipo de coluna que é passada como parâmetro: pode ser uma lista de valores
ou um mapa/diretório (chaves/valores)
.
Cenário 1¶
Entrada
Veja abaixo um exemplo de uso do posexplode
passando como parâmetro de uma lista de valores.
df = spark.createDataFrame(
[Row(a=1,
intlist=[1, 2, 3])])
df.select(posexplode(df.intlist)).collect()
Saída
A ferramenta adiciona o EWI SPRKPY1042
indicando que uma solução alternativa pode ser implementada.
df = spark.createDataFrame(
[Row(a=1,
intlist=[100, 200, 300])])
#EWI: SPRKPY1042 => pyspark.sql.functions.posexplode has a workaround, see documentation for more info
df.select(posexplode(df.intlist)).show()
Correção recomendada
Para ter o mesmo comportamento, use o método functions.flatten, elimine as colunas extras e renomeie os nomes das colunas de índice e valor.
df = spark.createDataFrame(
[Row(a=1,
intlist=[1, 2, 3])])
df.select(
flatten(df.intlist))\
.drop("DATA", "SEQ", "KEY", "PATH", "THIS")\
.rename({"INDEX": "pos", "VALUE": "col"}).show()
Cenário 2¶
Entrada
Abaixo está outro exemplo de uso do posexplode
passando como parâmetro um mapa/dicionário (chaves/valores)
df = spark.createDataFrame([
[1, [1, 2, 3], {"Ashi Garami": "Single Leg X"}, "Kimura"],
[2, [11, 22], {"Sankaku": "Triangle"}, "Coffee"]
],
schema=["idx", "lists", "maps", "strs"])
df.select(posexplode(df.maps)).show()
Saída
A ferramenta adiciona o EWI SPRKPY1042
indicando que uma solução alternativa pode ser implementada.
df = spark.createDataFrame([
[1, [1, 2, 3], {"Ashi Garami": "Single Leg X"}, "Kimura"],
[2, [11, 22], {"Sankaku": "Triangle"}, "Coffee"]
],
schema=["idx", "lists", "maps", "strs"])
#EWI: SPRKPY1042 => pyspark.sql.functions.posexplode has a workaround, see documentation for more info
df.select(posexplode(df.maps)).show()
Correção recomendada
Como solução alternativa, você pode usar functions.row_number para obter a posição e functions.explode com o nome do campo para obter o valor da chave/valor para dicionários.
df = spark.createDataFrame([
[10, [1, 2, 3], {"Ashi Garami": "Single Leg X"}, "Kimura"],
[11, [11, 22], {"Sankaku": "Triangle"}, "Coffee"]
],
schema=["idx", "lists", "maps", "strs"])
window = Window.orderBy(col("idx").asc())
df.select(
row_number().over(window).alias("pos"),
explode(df.maps).alias("key", "value")).show()
Observação: usar row_number não é totalmente equivalente, pois começa com 1 (não zero como o método spark)
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1013¶
Mensagem: pyspark.sql.functions.acosh tem uma solução alternativa
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.functions.acosh, que tem uma solução alternativa.
Cenário¶
Entrada
Neste exemplo, o pyspark calcula o acosh para um dataframe usando pyspark.sql.functions.acosh
from pyspark.sql import SparkSession
from pyspark.sql.functions import acosh
spark = SparkSession.builder.getOrCreate()
data = [['V1', 30],
['V2', 60],
['V3', 50],
['V4', 13]]
columns = ['Paremeter', 'value']
df = spark.createDataFrame(data, columns)
df_with_acosh = df.withColumn("acosh_value", acosh(df["value"]))
Saída
O SMA retorna o EWI SPRKPY1013 sobre a linha em que acosh é usado, para que você possa identificar onde corrigir.
from snowflake.snowpark import Session
spark = Session.builder.getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":0,"minor":0,"patch":0},"attributes":{"language":"Python"}})
data = [['V1', 30],
['V2', 60],
['V3', 50],
['V4', 13]]
columns = ['Paremeter', 'value']
df = spark.createDataFrame(data, columns)
#EWI: SPRKPY1013 => pyspark.sql.functions.acosh has a workaround, see documentation for more info
df_with_acosh = df.withColumn("acosh_value", acosh(df["value"]))
Correção recomendada
Não há implementação direta de «acosh», mas, em vez disso, pode-se usar «call_function «, usando «acosh» como o primeiro parâmetro e colName como o segundo.
import snowflake.snowpark as snowpark
from snowflake.snowpark import Session
from snowflake.snowpark.functions import call_function, col
spark = Session.builder.getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":0,"minor":0,"patch":0},"attributes":{"language":"Python"}})
data = [['V1', 30],
['V2', 60],
['V3', 50],
['V4', 13]]
columns = ['Paremeter', 'value']
df = spark.createDataFrame(data, columns)
df_with_acosh = df.select(call_function('ACOSH', col('value')))
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1085¶
Mensagem: pyspark.ml.feature.VectorAssembler não é compatível.
Categoria: Aviso
Descrição¶
O recurso pyspark.ml.feature.VectorAssembler não é compatível.
Cenário¶
Código de entrada
VectorAssembler é usado para combinar várias colunas em um único vetor.
data = [
(1, 10.0, 20.0),
(2, 25.0, 30.0),
(3, 50.0, 60.0)
]
df = SparkSession.createDataFrame(data, schema=["Id", "col1", "col2"])
vector = VectorAssembler(inputCols=["col1", "col2"], output="cols")
Código de saída
A ferramenta adiciona esse EWI SPRKPY1085
no código de saída para que você saiba que essa classe não é compatível com o Snowpark.
data = [
(1, 10.0, 20.0),
(2, 25.0, 30.0),
(3, 50.0, 60.0)
]
df = spark.createDataFrame(data, schema=["Id", "col1", "col2"])
#EWI: SPRKPY1085 => The pyspark.ml.feature.VectorAssembler function is not supported.
vector = VectorAssembler(inputCols=["col1", "col2"], output="cols")
Correção recomendada
O pyspark.ml.feature.VectorAssembler não tem uma correção recomendada.
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1027¶
Aviso
Esse código de problema foi depreciado desde o Spark Conversion Core 4.5.2
Mensagem: pyspark.sql.readwriter.DataFrameReader.json tem uma solução alternativa, consulte a documentação para obter mais informações
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.sql.readwriter.DataFrameReader.json, que tem uma solução alternativa.
Cenário¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.readwriter.DataFrameReader.json
que gera este EWI. Neste exemplo, a função json
é usada para ler vários arquivos . json
com um determinado esquema e usa algumas opções extras, como primitiveAsString e dateFormat para ajustar o comportamento da leitura dos arquivos.
file_paths = [
"path/to/your/file1.json",
"path/to/your/file2.json",
"path/to/your/file3.json",
]
df = session.read.json(
file_paths,
schema=my_schema,
primitiveAsString=True,
dateFormat="2023-06-20"
)
Saída
O SMA adiciona o EWI SPRKPY1027
ao código de saída para que você saiba que essa função não é diretamente compatível com o Snowpark, mas tem uma solução alternativa.
file_paths = [
"path/to/your/file1.json",
"path/to/your/file2.json",
"path/to/your/file3.json",
]
#EWI: SPRKPY1027 => pyspark.sql.readwriter.DataFrameReader.json has a workaround, see documentation for more info
df = session.read.json(
file_paths,
schema=my_schema,
primitiveAsString=True,
dateFormat="2023-06-20"
)
Correção recomendada
Nesta seção, explicamos como configurar o parâmetro path
, o parâmetro schema
e algumas opções
para fazê-los funcionar no Snowpark.
1. parâmetro path
O Snowpark exige que o parâmetro path seja um local de estágio, portanto, como solução alternativa, você pode criar um estágio temporário e adicionar cada arquivo .json
a esse estágio usando o prefixo file://
.
2. parâmetro schema
O Snowpark não permite definir schema como um parâmetro da função json
. Como solução alternativa, você pode usar a função snowflake.snowpark.DataFrameReader.schema.
3. parâmetros de options
O Snowpark não permite definir opções extras como parâmetros da função json
. Como solução alternativa, para muitos deles, você pode usar a função snowflake.snowpark.DataFrameReader.option para especificar esses parâmetros como opções do DataFrameReader.
Nota
As seguintes opções não são suportadas pelo Snowpark:
allowBackslashEscapingAnyCharacter
allowComments
allowNonNumericNumbers
allowNumericLeadingZero
allowSingleQuotes
allowUnquotedControlChars
allowUnquotedFieldNames
columnNameOfCorruptRecord
dropFiledIfAllNull
encoding
ignoreNullFields
lineSep
locale
mode
multiline
prefereDecimal
primitiveAsString
samplingRatio
timestampNTZFormat
timeZone
Abaixo está o exemplo completo de como o código de entrada deve ficar depois de aplicar as sugestões mencionadas acima para fazê-lo funcionar no Snowpark:
stage = f'{session.get_fully_qualified_current_schema()}.{_generate_prefix("TEMP_STAGE")}'
session.sql(f'CREATE TEMPORARY STAGE IF NOT EXISTS {stage}')
session.file.put(f"file:///path/to/your/file1.json", f"@{stage}")
session.file.put(f"file:///path/to/your/file2.json", f"@{stage}")
session.file.put(f"file:///path/to/your/file3.json", f"@{stage}")
df = session.read.schema(my_schema).option("dateFormat", "2023-06-20").json(stage)
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1076¶
Mensagem: Os parâmetros nos métodos pyspark.sql.readwriter.DataFrameReader não são suportados. Isso se aplica aos métodos CSV, JSON e PARQUET.
Categoria: Aviso.
Descrição¶
Para os métodos CSV, JSON e PARQUET no objeto pyspark.sql.readwriter.DataFrameReader, a ferramenta analisará os parâmetros e adicionará uma transformação de acordo com cada caso:
Todos os parâmetros correspondem ao seu nome equivalente no Snowpark: nesse caso, a ferramenta transformará o parâmetro em uma chamada .option(). Nesse caso, o parâmetro não adicionará esse EWI.
Alguns parâmetros não correspondem ao equivalente no Snowpark: nesse caso, a ferramenta adicionará esse EWI com as informações do parâmetro e o removerá da chamada do método.
Lista de equivalências:
Equivalências para CSV:
Chaves do Spark |
Equivalências do Snowpark |
---|---|
sep |
FIELD_DELIMITER |
header |
PARSE_HEADER |
lineSep |
RECORD_DELIMITER |
pathGlobFilter |
PATTERN |
quote |
FIELD_OPTIONALLY_ENCLOSED_BY |
nullValue |
NULL_IF |
dateFormat |
DATE_FORMAT |
timestampFormat |
TIMESTAMP_FORMAT |
inferSchema |
INFER_SCHEMA |
delimiter |
FIELD_DELIMITER |
Equivalências para JSON:
Chaves do Spark |
Equivalências do Snowpark |
---|---|
dateFormat |
DATE_FORMAT |
timestampFormat |
TIMESTAMP_FORMAT |
pathGlobFilter |
PATTERN |
Equivalências para PARQUET:
Chaves do Spark |
Equivalências do Snowpark |
---|---|
pathGlobFilter |
PATTERN |
Cenários¶
Cenário 1¶
Entrada
Para CVS, aqui estão alguns exemplos:
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName('myapp').getOrCreate()
spark.read.csv("path3", None,None,None,None,None,None,True).show()
Saída
No código convertido, os parâmetros são adicionados como opções individuais à função cvs
from snowflake.snowpark import Session
spark = Session.builder.app_name('myapp', True).getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":0,"minor":0,"patch":0},"attributes":{"language":"Python"}})
#EWI: SPRKPY1076 => Some of the included parameters are not supported in the csv function, the supported ones will be added into a option method.
spark.read.option("FIELD_DELIMITER", None).option("PARSE_HEADER", True).option("FIELD_OPTIONALLY_ENCLOSED_BY", None).csv("path3").show()
Cenário 2¶
Entrada
Para JSON, aqui estão alguns exemplos:
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName('myapp').getOrCreate()
spark.read.json("/myPath/jsonFile/", dateFormat='YYYY/MM/DD').show()
Saída
No código convertido, os parâmetros são adicionados como opções individuais à função json
from snowflake.snowpark import Session
spark = Session.builder.app_name('myapp', True).getOrCreate()
#EWI: SPRKPY1076 => Some of the included parameters are not supported in the json function, the supported ones will be added into a option method.
spark.read.option("DATE_FORMAT", 'YYYY/MM/DD').json("/myPath/jsonFile/").show()
Cenário 3¶
Entrada
Para PARQUET, aqui estão alguns exemplos:
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName('myapp').getOrCreate()
spark.read.parquet("/path/to/my/file.parquet", pathGlobFilter="*.parquet").show()
Saída
No código convertido, os parâmetros são adicionados como opções individuais à função parquet
from snowflake.snowpark import Session
spark = Session.builder.app_name('myapp', True).getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":0,"minor":0,"patch":0},"attributes":{"language":"Python"}})
#EWI: SPRKPY1076 => Some of the included parameters are not supported in the parquet function, the supported ones will be added into a option method.
#EWI: SPRKPY1029 => The parquet function require adjustments, in Snowpark the parquet files needs to be located in an stage. See the documentation for more info.
spark.read.option("PATTERN", "*.parquet").parquet("/path/to/my/file.parquet")
Recomendações adicionais¶
Quando houver parâmetros não equivalentes, é recomendável verificar o comportamento após a transformação.
Além disso, a documentação pode ser útil para encontrar um ajuste melhor:
Documentação de opções para CSV:
Documentação de opções para JSON:
Documentação de opções para PARQUET:
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1066¶
Mensagem: O elemento Spark não se aplica, pois o Snowflake usa o mecanismo de micropartição criado automaticamente.
Categoria: Aviso
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de elementos relacionados a partições:
Esses elementos não se aplicam devido ao uso de micropartições do Snowflake.
Código de entrada
Neste exemplo sortWithinPartitions ele é usado para criar uma partição em um DataFrame classificado pela coluna especificada.
df = spark.createDataFrame([(2, "Alice"), (5, "Bob")], schema=["age", "name"])
df.sortWithinPartitions("age", ascending=False)
Código de saída
O SMA adiciona uma mensagem EWI indicando que o elemento Spark não é necessário.
df = spark.createDataFrame([(2, "Alice"), (5, "Bob")], schema=["age", "name"])
#EWI: SPRKPY1066 => The element does not apply since snowflake use micro-partitioning mechanism are created automatically.
df.sortWithinPartitions("age", ascending=False)
Correção recomendada
Remova o uso do elemento.
df = spark.createDataFrame([(2, "Alice"), (5, "Bob")], schema=["age", "name"])
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1037¶
Aviso
Este código de problema está obsoleto
Mensagem: pyspark.sql.functions.sort_array tem uma solução alternativa, consulte a documentação para obter mais informações
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.sql.functions.sort_array, que tem uma solução alternativa.
Cenário¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.functions.sort_array
que gera esse EWI. Neste exemplo, a função sort_array
é usada para classificar a matriz numbers em ordem crescente e decrescente.
df = spark.createDataFrame([(1, [3, 1, 2]), (2, [10, 5, 8]), (3, [6, 4, 7])], ["id", "numbers"])
df_sorted_asc = df.withColumn("sorted_numbers_asc", sort_array("numbers", asc=True))
df_sorted_desc = df.withColumn("sorted_numbers_desc", sort_array("numbers", asc=False))
Saída
O SMA adiciona o EWI SPRKPY1037
ao código de saída para que você saiba que essa função não é diretamente compatível com o Snowpark, mas tem uma solução alternativa.
df = spark.createDataFrame([(1, [3, 1, 2]), (2, [10, 5, 8]), (3, [6, 4, 7])], ["id", "numbers"])
#EWI: SPRKPY1037 => pyspark.sql.functions.sort_array has a workaround, see documentation for more info
df_sorted_asc = df.withColumn("sorted_numbers_asc", sort_array("numbers", asc=True))
#EWI: SPRKPY1037 => pyspark.sql.functions.sort_array has a workaround, see documentation for more info
df_sorted_desc = df.withColumn("sorted_numbers_desc", sort_array("numbers", asc=False))
Correção recomendada
Como solução alternativa, você pode importar o pacote snowpark_extensions, que fornece uma extensão para a função sort_array
.
import snowpark_extensions
df = spark.createDataFrame([(1, [3, 1, 2]), (2, [10, 5, 8]), (3, [6, 4, 7])], ["id", "numbers"])
df_sorted_asc = df.withColumn("sorted_numbers_asc", sort_array("numbers", asc=True))
df_sorted_desc = df.withColumn("sorted_numbers_desc", sort_array("numbers", asc=False))
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1003¶
Message : Ocorreu um erro ao carregar a tabela de símbolos.
Category : Erro de conversão.
Descrição¶
Esse problema aparece quando há um erro ao processar os símbolos na tabela de símbolos. A tabela de símbolos faz parte da arquitetura subjacente do SMA, permitindo conversões mais complexas. Esse erro pode ser devido a uma declaração inesperada no código-fonte.
Recomendações adicionais ¶
É improvável que isso seja um erro no próprio código-fonte, mas sim um erro na forma como a ferramenta processa o código-fonte. A melhor solução seria publicar um problema no SMA.
Para obter mais suporte, você pode enviar um e-mail para sma-support@snowflake.com ou publicar um problema no SMA.
SPRKPY1052¶
Aviso
Esse código de problema foi depreciado desde o Spark Conversion Core Version 2.8.0
Mensagem: pyspark.sql.session.SparkSession.Builder.enableHiveSupport tem uma solução alternativa
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso do pyspark.sql.session.SparkSession.Builder.enableHiveSupport que tem uma solução alternativa.
Cenário¶
Entrada
Abaixo está um exemplo que configura o SparkSession e habilita o suporte para Hive usando o método enableHiveSupport
.
spark = Session.builder.appName("Merge_target_table")\
.config("spark.port.maxRetries","100") \
.enableHiveSupport().getOrCreate()
Saída
A ferramenta adiciona o EWI SPRKPY1052
indicando que uma solução alternativa pode ser implementada.
#EWI: SPRKPY1052 => pyspark.sql.session.SparkSession.Builder.enableHiveSupport has a workaround, see documentation for more info
spark = Session.builder.appName("Merge_target_table")\
.config("spark.port.maxRetries","100") \
.enableHiveSupport().getOrCreate()
Correção recomendada
Remova o uso da função enableHiveSupport
porque ela não é necessária no Snowpark.
spark = Session.builder.appName("Merge_target_table")\
.config("spark.port.maxRetries","100") \
.getOrCreate()
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1043¶
Mensagem: pyspark.sql.functions.posexplode_outer tem uma solução alternativa
Categoria: Aviso
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.functions.posexplode_outer, que tem uma solução alternativa.
Cenários¶
Há alguns cenários com os quais esse método pode lidar, dependendo do tipo de coluna que é passada como parâmetro: pode ser uma lista de valores
ou um mapa/diretório (chaves/valores)
.
Cenário 1¶
Entrada
Abaixo está um exemplo que mostra o uso de posexplode_outer
passando uma lista de valores.
df = spark.createDataFrame(
[
(1, ["foo", "bar"]),
(2, []),
(3, None)],
("id", "an_array"))
df.select("id", "an_array", posexplode_outer("an_array")).show()
Saída
A ferramenta adiciona o EWI SPRKPY1043
indicando que uma solução alternativa pode ser implementada.
df = spark.createDataFrame(
[
(1, ["foo", "bar"]),
(2, []),
(3, None)],
("id", "an_array"))
#EWI: SPRKPY1043 => pyspark.sql.functions.posexplode_outer has a workaround, see documentation for more info
df.select("id", "an_array", posexplode_outer("an_array")).show()
Correção recomendada
Para ter o mesmo comportamento, use o método functions.flatten enviando o parâmetro outer
em True, elimine as colunas extras e renomeie os nomes das colunas de índice e valor.
df = spark.createDataFrame(
[
(1, ["foo", "bar"]),
(2, []),
(3, None)],
("id", "an_array"))
df.select(
flatten(df.an_array, outer=True))\
.drop("DATA", "SEQ", "KEY", "PATH", "THIS")\
.rename({"INDEX": "pos", "VALUE": "col"}).show()
Cenário 2¶
Entrada
Abaixo está outro exemplo de uso do posexplode_outer passando um mapa/dicionário (chaves/valores)
df = spark.createDataFrame(
[
(1, {"x": 1.0}),
(2, {}),
(3, None)],
("id", "a_map"))
df.select(posexplode_outer(df.a_map)).show()
Saída
A ferramenta adiciona o EWI SPRKPY1043
indicando que uma solução alternativa pode ser implementada.
df = spark.createDataFrame(
[
(1, {"x": "Ashi Garami"}),
(2, {}),
(3, None)],
("id", "a_map"))
#EWI: SPRKPY1043 => pyspark.sql.functions.posexplode_outer has a workaround, see documentation for more info
df.select(posexplode_outer(df.a_map)).show()
Correção recomendada
Como solução alternativa, você pode usar functions.row_number para obter a posição e functions.explode_outer com o nome do campo para obter o valor da chave/valor para dicionários.
df = spark.createDataFrame(
[
(1, {"x": "Ashi Garami"}),
(2, {}),
(3, None)],
("id", "a_map"))
window = Window.orderBy(col("id").asc())
df.select(
row_number().over(window).alias("pos"),
explode_outer(df.a_map)).show()
Observação: usar row_number não é totalmente equivalente, pois começa com 1 (não zero como o método spark)
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1012¶
Aviso
Este código de problema está obsoleto
Mensagem: pyspark.sql.dataframe.DataFrameStatFunctions.writeTo tem uma solução alternativa
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.dataframe.DataFrameStatFunctions.writeTo que tem uma solução alternativa.
Cenário¶
Entrada
Neste exemplo, o dataframe df é gravado em uma tabela Spark «table».
writer = df.writeTo("table")
Saída
O SMA retorna o EWI SPRKPY1012 sobre a linha em que DataFrameStatFunctions.writeTo é usado, para que você possa identificar o local a ser corrigido.
#EWI: SPRKPY1012 => pyspark.sql.dataframe.DataFrameStatFunctions.writeTo has a workaround, see documentation for more info
writer = df.writeTo("table")
Correção recomendada
Em vez disso, use df.write.SaveAsTable().
import df.write as wt
writer = df.write.save_as_table(table)
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1084¶
Esse código de problema foi depreciado desde o Spark Conversion Core 4.12.0
Mensagem: pyspark.sql.readwriter.DataFrameWriter.option não é compatível.
Categoria: Aviso
Descrição¶
A função pyspark.sql.readwriter.DataFrameWriter.option não é suportada.
Cenário¶
Código de entrada
Abaixo está um exemplo usando o método option
, esse método é usado para adicionar configurações adicionais ao gravar os dados de um DataFrame.
path_csv_file = "/path/to/file.csv"
data = [
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
df.write.option("header", True).csv(csv_file_path)
df.write.option("sep", ";").option("lineSep","-").csv(csv_file_path)
Código de saída
A ferramenta adiciona esse EWI SPRKPY1084
no código de saída para que você saiba que essa função não é compatível com o Snowpark.
path_csv_file = "/path/to/file.csv"
data = [
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
#EWI: SPRKPY1084 => The pyspark.sql.readwriter.DataFrameWriter.option function is not supported.
df.write.option("header", True).csv(csv_file_path)
#EWI: SPRKPY1084 => The pyspark.sql.readwriter.DataFrameWriter.option function is not supported.
df.write.option("sep", ";").option("lineSep","-").csv(csv_file_path)
Correção recomendada
O método pyspark.sql.readwriter.DataFrameWriter.option não tem uma correção recomendada.
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1026¶
Aviso
Esse código de problema foi depreciado desde o Spark Conversion Core 4.3.2
Mensagem: pyspark.sql.readwriter.DataFrameReader.csv tem uma solução alternativa, consulte a documentação para obter mais informações
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.sql.readwriter.DataFrameReader.csv, que tem uma solução alternativa.
Cenário¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.readwriter.DataFrameReader.csv
que gera este EWI. Neste exemplo, a função csv
é usada para ler vários arquivos .csv
com um determinado esquema e usa algumas opções extras, como encoding, header e sep para ajustar o comportamento da leitura dos arquivos.
file_paths = [
"path/to/your/file1.csv",
"path/to/your/file2.csv",
"path/to/your/file3.csv",
]
df = session.read.csv(
file_paths,
schema=my_schema,
encoding="UTF-8",
header=True,
sep=","
)
Saída
O SMA adiciona o EWI SPRKPY1026
ao código de saída para que você saiba que essa função não é diretamente compatível com o Snowpark, mas tem uma solução alternativa.
file_paths = [
"path/to/your/file1.csv",
"path/to/your/file2.csv",
"path/to/your/file3.csv",
]
#EWI: SPRKPY1026 => pyspark.sql.readwriter.DataFrameReader.csv has a workaround, see documentation for more info
df = session.read.csv(
file_paths,
schema=my_schema,
encoding="UTF-8",
header=True,
sep=","
)
Correção recomendada
Nesta seção, explicamos como configurar o parâmetro path
, o parâmetro schema
e algumas opções
para fazê-los funcionar no Snowpark.
1. parâmetro path
O Snowpark exige que o parâmetro path seja um local de estágio, portanto, como solução alternativa, você pode criar um estágio temporário e adicionar cada arquivo .csv
a esse estágio usando o prefixo file://
.
2. parâmetro schema
O Snowpark não permite definir schema como um parâmetro da função csv
. Como solução alternativa, você pode usar a função snowflake.snowpark.DataFrameReader.schema.
3. parâmetros de options
O Snowpark não permite definir as opções extras como parâmetros da função csv
. Como solução alternativa, para muitos deles, você pode usar a função snowflake.snowpark.DataFrameReader.option para especificar esses parâmetros como opções do DataFrameReader.
Nota
As seguintes opções não são suportadas pelo Snowpark:
columnNameOfCorruptRecord
emptyValue
enforceSchema
header
ignoreLeadingWhiteSpace
ignoreTrailingWhiteSpace
inferSchema
locale
maxCharsPerColumn
maxColumns
mode
multiLine
nanValue
negativoInf
nullValue
positivoInf
quoteAll
samplingRatio
timestampNTZFormat
unescapedQuoteHandling
Abaixo está o exemplo completo de como o código de entrada deve ficar depois de aplicar as sugestões mencionadas acima para fazê-lo funcionar no Snowpark:
stage = f'{session.get_fully_qualified_current_schema()}.{_generate_prefix("TEMP_STAGE")}'
session.sql(f'CREATE TEMPORARY STAGE IF NOT EXISTS {stage}')
session.file.put(f"file:///path/to/your/file1.csv", f"@{stage}")
session.file.put(f"file:///path/to/your/file2.csv", f"@{stage}")
session.file.put(f"file:///path/to/your/file3.csv", f"@{stage}")
df = session.read.schema(my_schema).option("encoding", "UTF-8").option("sep", ",").csv(stage)
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1077¶
Mensagem: o código SQL incorporado não pode ser processado.
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta um código SQL incorporado que não pode ser convertido para o Snowpark.
Consulte a seção de código SQL incorporado para obter mais informações.
Cenário¶
Entrada
Neste exemplo, o código SQL está incorporado em uma variável chamada query, que é usada como parâmetro para o método Pyspark.sql.
query = f"SELECT * from myTable"
spark.sql(query)
Saída
O SMA detecta que o parâmetro PySpark.sql é uma variável e não um código SQL, portanto, a mensagem EWI SPRKPY1077 é adicionada à linha PySpark.sql.
query = f"SELECT * myTable"
#EWI: SPRKPY1077 => SQL embedded code cannot be processed.
spark.sql(query)
Recomendações adicionais¶
Para a transformação de SQL, esse código deve estar diretamente dentro como parâmetro do método apenas como valores de cadeia de caracteres e sem interpolação. Verifique o envio de SQL para a função PySpark.SQL para validar sua funcionalidade no Snowflake.
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1067¶
Mensagem: O pyspark.sql.functions.split tem parâmetros que não são suportados pelo Snowpark.
Categoria: Aviso
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.functions.split com mais de dois parâmetros ou um padrão regex como parâmetro; ambos os casos não são suportados.
Cenários¶
Cenário 1¶
Código de entrada
Neste exemplo, a função split tem mais de dois parâmetros.
df.select(split(columnName, ",", 5))
Código de saída
A ferramenta adiciona esse EWI no código de saída para informar que essa função não é suportada quando tem mais de dois parâmetros.
#EWI: SPRKPY1067 => Snowpark does not support split functions with more than two parameters or containing regex pattern. See documentation for more info.
df.select(split(columnName, ",", 5))
Correção recomendada
Mantenha a função split com apenas dois parâmetros.
df.select(split(columnName, ","))
Cenário 2¶
Código de entrada
Neste exemplo, a função split tem um padrão regex como parâmetro.
df.select(split(columnName, "^([\d]+-[\d]+-[\d])"))
Código de saída
A ferramenta adiciona esse EWI no código de saída para informar que essa função não é suportada quando tem um padrão regex como parâmetro.
#EWI: SPRKPY1067 => Snowpark does not support split functions with more than two parameters or containing regex pattern. See documentation for more info.
df.select(split(columnName, "^([\d]+-[\d]+-[\d])"))
Correção recomendada
A assinatura do spark para esse método functions.split(str: ColumnOrName, pattern: str, limit: int = - 1)
não corresponde exatamente ao método no Snowpark functions.split(str: Union[Column, str], pattern: Union[Column, str])
portanto, por enquanto, o cenário que usa expressão regular não tem uma correção recomendada.
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1036¶
Aviso
Este código de problema está obsoleto
Mensagem: pyspark.sql.column.Column.getField tem uma solução alternativa, consulte a documentação para obter mais informações
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.sql.column.Column.getField, que tem uma solução alternativa.
Cenário¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.column.Column.getField
que gera esse EWI. Neste exemplo, a função getField
é usada para extrair o nome da coluna info.
df = spark.createDataFrame([(1, {"name": "John", "age": 30}), (2, {"name": "Jane", "age": 25})], ["id", "info"])
df_with_name = df.withColumn("name", col("info").getField("name"))
Saída
O SMA adiciona o EWI SPRKPY1036
ao código de saída para que você saiba que essa função não é diretamente compatível com o Snowpark, mas tem uma solução alternativa.
df = spark.createDataFrame([(1, {"name": "John", "age": 30}), (2, {"name": "Jane", "age": 25})], ["id", "info"])
#EWI: SPRKPY1036 => pyspark.sql.column.Column.getField has a workaround, see documentation for more info
df_with_name = df.withColumn("name", col("info").getField("name"))
Correção recomendada
Como solução alternativa, você pode usar o operador de indexador de coluna do Snowpark com o nome do campo como índice.
df = spark.createDataFrame([(1, {"name": "John", "age": 30}), (2, {"name": "Jane", "age": 25})], ["id", "info"])
df_with_name = df.withColumn("name", col("info")["name"])
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1002¶
Message : < elemento > não é suportado, elemento Spark não é suportado.
Category : Erro de conversão.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de um elemento que não é compatível com o Snowpark e não tem seu próprio código de erro associado a ele. Esse é o código de erro genérico usado pelo SMA para um elemento sem suporte.
Recomendações adicionais¶
Mesmo que a opção ou o elemento da mensagem não seja compatível, isso não significa que não seja possível encontrar uma solução. Isso significa apenas que a ferramenta em si não consegue encontrar a solução.
Se encontrou um elemento não suportado de uma biblioteca pyspark.ml, considere uma abordagem alternativa. Há guias adicionais disponíveis para solucionar problemas relacionados ao ml, como este do Snowflake.
Verifique se o código-fonte tem a sintaxe correta. (Você pode usar o arquivo issues.csv para determinar onde estão ocorrendo os erros de conversão) Se a sintaxe estiver correta, informe que encontrou um erro de conversão em um elemento específico usando a opção de Relatar um problema no SMA. Inclua a linha de código que estava causando o erro na descrição quando registrar esse problema.
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1053¶
Mensagem: Ocorreu um erro ao extrair os arquivos dbc.
Categoria: Aviso.
Descrição¶
Esse problema aparece quando um arquivo dbc não pode ser extraído. Esse aviso pode ser causado por um ou mais dos seguintes motivos: muito pesado, inacessível, somente leitura, etc.
Recomendações adicionais¶
Como solução alternativa, você pode verificar o tamanho do arquivo se ele for muito pesado para ser processado. Além disso, analise se a ferramenta pode acessá-la para evitar problemas de acesso.
Para obter mais suporte, envie um e-mail para snowconvert-info@snowflake.com. Se tiver um contrato de suporte com a Snowflake, entre em contato com seu engenheiro de vendas para que ele possa direcionar suas necessidades de suporte.
SPRKPY1080¶
Mensagem: O valor de SparkContext é substituído pela variável “session”.
Categoria: Aviso
Descrição¶
O contexto do Spark é armazenado em uma variável chamada session que cria uma sessão do Snowpark.
Cenário¶
Entrada
Este snippet descreve um SparkContext
## Input Code
from pyspark import SparkContext
from pyspark.sql import SparkSession
def example1():
sc = SparkContext("local[*]", "TestApp")
sc.setLogLevel("ALL")
sc.setLogLevel("DEBUG")
Saída
Nesse código de saída, o SMA substituiu o PySpark.SparkContext por um SparkSession, observe que o SMA também adiciona um modelo para substituir a conexão no arquivo «connection.json» e, em seguida, carrega essa configuração na variável connection_parameter.
## Output Code
import logging
import sys
import json
from snowflake.snowpark import Session
from snowflake.snowpark import Session
def example1():
jsonFile = open("connection.json")
connection_parameter = json.load(jsonFile)
jsonFile.close()
#EWI: SPRKPY1080 => The value of SparkContext is replaced with 'session' variable.
sc = Session.builder.configs(connection_parameter).getOrCreate()
sc.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":0,"minor":0,"patch":0},"attributes":{"language":"Python"}})
logging.basicConfig(stream = sys.stdout, level = logging.NOTSET)
logging.basicConfig(stream = sys.stdout, level = logging.DEBUG)
Correção recomendada
O arquivo de configuração «connection.json» deve ser atualizado com as informações de conexão necessárias:
{
"user": "my_user",
"password": "my_password",
"account": "my_account",
"role": "my_role",
"warehouse": "my_warehouse",
"database": "my_database",
"schema": "my_schema"
}
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1073¶
Mensagem: pyspark.sql.functions.udf sem parâmetros ou parâmetro de tipo de retorno não são suportados
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.functions.udf como função ou decorador e não é suportado em dois casos específicos, quando não tem parâmetros ou parâmetro de tipo de retorno.
Cenários¶
Cenário 1¶
Entrada
No Pyspark, você pode criar uma Função Definida pelo Usuário sem parâmetros de entrada ou de tipo de retorno:
from pyspark.sql import SparkSession, DataFrameStatFunctions
from pyspark.sql.functions import col, udf
spark = SparkSession.builder.getOrCreate()
data = [['Q1', 'Test 1'],
['Q2', 'Test 2'],
['Q3', 'Test 1'],
['Q4', 'Test 1']]
columns = ['Quadrant', 'Value']
df = spark.createDataFrame(data, columns)
my_udf = udf(lambda s: len(s))
df.withColumn('Len Value' ,my_udf(col('Value')) ).show()
Saída
O Snowpark requer os tipos de entrada e retorno para a função Udf. Porque eles não são fornecidos e o SMA não pode usar esses parâmetros.
from snowflake.snowpark import Session, DataFrameStatFunctions
from snowflake.snowpark.functions import col, udf
spark = Session.builder.getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":0,"minor":0,"patch":0},"attributes":{"language":"Python"}})
data = [['Q1', 'Test 1'],
['Q2', 'Test 2'],
['Q3', 'Test 1'],
['Q4', 'Test 1']]
columns = ['Quadrant', 'Value']
df = spark.createDataFrame(data, columns)
#EWI: SPRKPY1073 => pyspark.sql.functions.udf function without the return type parameter is not supported. See documentation for more info.
my_udf = udf(lambda s: len(s))
df.withColumn('Len Value' ,my_udf(col('Value')) ).show()
Correção recomendada
Para corrigir esse cenário, é necessário adicionar a importação para os tipos de retorno de entrada e saída e, em seguida, os parâmetros de retornotype e input_types[] na função udf _my_udf.
from snowflake.snowpark import Session, DataFrameStatFunctions
from snowflake.snowpark.functions import col, udf
from snowflake.snowpark.types import IntegerType, StringType
spark = Session.builder.getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":0,"minor":0,"patch":0},"attributes":{"language":"Python"}})
data = [['Q1', 'Test 1'],
['Q2', 'Test 2'],
['Q3', 'Test 1'],
['Q4', 'Test 1']]
columns = ['Quadrant', 'Value']
df = spark.createDataFrame(data, columns)
my_udf = udf(lambda s: len(s), return_type=IntegerType(), input_types=[StringType()])
df.with_column("result", my_udf(df.Value)).show()
Cenário 2¶
No PySpark, você pode usar um decorador @udf sem parâmetros
Entrada
from pyspark.sql.functions import col, udf
spark = SparkSession.builder.getOrCreate()
data = [['Q1', 'Test 1'],
['Q2', 'Test 2'],
['Q3', 'Test 1'],
['Q4', 'Test 1']]
columns = ['Quadrant', 'Value']
df = spark.createDataFrame(data, columns)
@udf()
def my_udf(str):
return len(str)
df.withColumn('Len Value' ,my_udf(col('Value')) ).show()
Saída
No Snowpark, todos os parâmetros de um decorador udf são necessários.
from snowflake.snowpark.functions import col, udf
spark = Session.builder.getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":0,"minor":0,"patch":0},"attributes":{"language":"Python"}})
data = [['Q1', 'Test 1'],
['Q2', 'Test 2'],
['Q3', 'Test 1'],
['Q4', 'Test 1']]
columns = ['Quadrant', 'Value']
df = spark.createDataFrame(data, columns)
#EWI: SPRKPY1073 => pyspark.sql.functions.udf decorator without parameters is not supported. See documentation for more info.
@udf()
def my_udf(str):
return len(str)
df.withColumn('Len Value' ,my_udf(col('Value')) ).show()
Correção recomendada
Para corrigir esse cenário, é necessário adicionar a importação para os tipos de retorno da entrada e da saída e, em seguida, os parâmetros de return_type e input_types[] no decorador udf @udf.
from snowflake.snowpark.functions import col, udf
from snowflake.snowpark.types import IntegerType, StringType
spark = Session.builder.getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":0,"minor":0,"patch":0},"attributes":{"language":"Python"}})
data = [['Q1', 'Test 1'],
['Q2', 'Test 2'],
['Q3', 'Test 1'],
['Q4', 'Test 1']]
columns = ['Quadrant', 'Value']
df = spark.createDataFrame(data, columns)
@udf(return_type=IntegerType(), input_types=[StringType()])
def my_udf(str):
return len(str)
df.withColumn('Len Value' ,my_udf(col('Value')) ).show()
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1022¶
Mensagem: pyspark.sql.functions.log10 tem uma solução alternativa, consulte a documentação para obter mais informações
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.sql.functions.log10, que tem uma solução alternativa.
Cenário¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.functions.log10
que gera esse EWI. Neste exemplo, a função log10
é usada para calcular o logaritmo de base 10 da coluna value.
df = spark.createDataFrame([(1,), (10,), (100,), (1000,), (10000,)], ["value"])
df_with_log10 = df.withColumn("log10_value", log10(df["value"]))
Saída
O SMA adiciona o EWI SPRKPY1022
ao código de saída para que você saiba que essa função não é diretamente compatível com o Snowpark, mas tem uma solução alternativa.
df = spark.createDataFrame([(1,), (10,), (100,), (1000,), (10000,)], ["value"])
#EWI: SPRKPY1022 => pyspark.sql.functions.log10 has a workaround, see documentation for more info
df_with_log10 = df.withColumn("log10_value", log10(df["value"]))
Correção recomendada
Como solução alternativa, você pode usar a função snowflake.snowpark.functions.log passando o valor literal 10
como base.
df = spark.createDataFrame([(1,), (10,), (100,), (1000,), (10000,)], ["value"])
df_with_log10 = df.withColumn("log10_value", log(10, df["value"]))
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1016¶
Aviso
Esse código de problema foi depreciado desde o Spark Conversion Core Version 0.11.7
Mensagem: pyspark.sql.functions.collect_set tem uma solução alternativa
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.functions.collect_set, que tem uma solução alternativa.
Cenário¶
Entrada
Usando o conjuntocollect para obter os elementos de _colname sem duplicatas:
col = collect_set(colName)
Saída
O SMA retorna o EWI SPRKPY1016 sobre a linha em que collect_set é usado, para que você possa identificar onde corrigir.
#EWI: SPRKPY1016 => pyspark.sql.functions.collect_set has a workaround, see documentation for more info
col = collect_set(colName)
Correção recomendada
Use a função array_agg e adicione um segundo argumento com o valor True.
col = array_agg(col, True)
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1047¶
Aviso
Esse código de problema está obsoleto desde o Spark Conversion Core Version 4.6.0
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso do pyspark.context.SparkContext.setLogLevel que tem uma solução alternativa.
Cenário¶
Entrada
Veja a seguir um exemplo de uso do método setLogLevel
.
sparkSession.sparkContext.setLogLevel("WARN")
Saída
A ferramenta adiciona o EWI SPRKPY1047
indicando que uma solução alternativa pode ser implementada.
#EWI: SPRKPY1047 => pyspark.context.SparkContext.setLogLevel has a workaround, see documentation for more info
sparkSession.sparkContext.setLogLevel("WARN")
Correção recomendada
Substitua o uso da função setLogLevel
por logging.basicConfig
que fornece um conjunto de funções de conveniência para uso simples de registro. Para usá-lo, precisamos importar dois módulos, «logging» e «sys», e a constante de nível deve ser substituída usando a «Tabela de níveis equivalentes»:
import logging
import sys
logging.basicConfig(stream=sys.stdout, level=logging.WARNING)
Tabela de níveis equivalentes
Parâmetro de origem de nível |
Parâmetro de destino de nível |
---|---|
«ALL» |
Isso não tem equivalente |
«DEBUG» |
logging.DEBUG |
«ERROR» |
logging.ERROR |
«FATAL» |
logging.CRITICAL |
«INFO» |
logging.INFO |
«OFF» |
logging.NOTSET |
«TRACE» |
Isso não tem equivalente |
«WARN» |
logging.WARNING |
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1057¶
Aviso
Esse código de problema foi depreciado desde o Spark Conversion Core Version 4.8.0
Mensagem: O argumento da opção PySpark Dataframe contém um valor que não é um literal e, portanto, não pode ser avaliado
Categoria: Aviso.
Descrição¶
Esse código de problema está obsoleto. Se você estiver usando uma versão mais antiga, atualize para a mais recente.
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1006¶
Aviso
Esse código de problema foi depreciado desde o Spark Conversion Core Version 4.8.0
Message : pyspark.context.SparkContext não é necessário
Category : Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso do pyspark.context.SparkContext, que não é necessário no Snowflake.
Cenário¶
Entrada
Neste exemplo, há dois contextos para criar conexões com um Spark Cluster
from pyspark import SparkContext
sql_context1 = SparkContext(my_sc1)
sql_context2 = SparkContext(sparkContext=my_sc2)
Saída
Como não há clusters no Snowflake, o contexto não é necessário. Observe que as variáveis my_sc1 e my_sc2, que contêm propriedades do Spark, podem não ser necessárias ou terão de ser adaptadas para corrigir o código.
from snowflake.snowpark import Session
#EWI: SPRKPY1006 => pyspark.sql.context.SparkContext is not required
sql_context1 = my_sc1
#EWI: SPRKPY1006 => pyspark.sql.context.SparkContext is not required
sql_context2 = my_sc2
Recomendações adicionais¶
Esse é um parâmetro desnecessário que está sendo removido com a inserção de um comentário de aviso. Não deve haver nenhuma ação por parte do usuário.
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1032¶
Mensagem: _ spark element _ não está definido
Categoria: Erro de conversão
Descrição¶
Esse problema aparece quando o SMA não consegue determinar um status de mapeamento apropriado para um determinado elemento. Isso significa que o SMA ainda não sabe se esse elemento é compatível ou não com o Snowpark. Observe que esse é um código de erro genérico usado pelo SMA para qualquer elemento não definido.
Cenário¶
Entrada
Abaixo está um exemplo de uma função para a qual o SMA não conseguiu determinar um status de mapeamento adequado. Nesse caso, presuma que not_defined_function()
é uma função válida PySpark e o código é executado.
sc.parallelize(["a", "b", "c", "d", "e"], 3).not_defined_function().collect()
Saída
O SMA adiciona o EWI SPRKPY1032
ao código de saída para informar que esse elemento não está definido.
#EWI: SPRKPY1032 => pyspark.rdd.RDD.not_defined_function is not defined
sc.parallelize(["a", "b", "c", "d", "e"], 3).not_defined_function().collect()
Correção recomendada
Para tentar identificar o problema, você pode realizar as seguintes validações:
Verifique se o código-fonte tem a sintaxe correta e se está escrito corretamente.
Verifique se está usando uma versão do PySpark compatível com o SMA. Para saber qual versão do PySpark é compatível com o SMA no momento da execução do SMA, examine a primeira página do arquivo
DetailedReport.docx
.
Se esse for um elemento válido do PySpark, informe que encontrou um erro de conversão nesse elemento específico usando a opção de Relatar um problema do SMA e inclua qualquer informação adicional que considere útil.
Observe que, se um elemento não estiver definido, isso não significa que ele não seja compatível com o Snowpark. Consulte a documentação do Snowpark para verificar se existe um elemento equivalente.
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1063¶
Mensagem: pyspark.sql.pandas.functions.pandas_udf tem uma solução alternativa.
Categoria: Aviso
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.pandas.functions.pandas_udf, que tem uma solução alternativa.
Cenário¶
Entrada
A função pandas_udf é usada para criar funções definidas pelo usuário que trabalham com grandes quantidades de dados.
@pandas_udf(schema, PandasUDFType.GROUPED_MAP)
def modify_df(pdf):
return pd.DataFrame({'result': pdf['col1'] + pdf['col2'] + 1})
df = spark.createDataFrame([(1, 2), (3, 4), (1, 1)], ["col1", "col2"])
new_df = df.groupby().apply(modify_df)
Saída
O SMA adiciona uma mensagem EWI indicando que o pandas_udf tem uma solução alternativa.
#EWI: SPRKPY1062 => pyspark.sql.pandas.functions.pandas_udf has a workaround, see documentation for more info
@pandas_udf(schema, PandasUDFType.GROUPED_MAP)
def modify_df(pdf):
return pd.DataFrame({'result': pdf['col1'] + pdf['col2'] + 1})
df = spark.createDataFrame([(1, 2), (3, 4), (1, 1)], ["col1", "col2"])
new_df = df.groupby().apply(modify_df)
Correção recomendada
Especifique explicitamente os tipos de parâmetros como um novo parâmetro input_types
e remova o parâmetro functionType
, se aplicável. A função criada deve ser chamada dentro de uma instrução select.
@pandas_udf(
return_type = schema,
input_types = [PandasDataFrameType([IntegerType(), IntegerType()])]
)
def modify_df(pdf):
return pd.DataFrame({'result': pdf['col1'] + pdf['col2'] + 1})
df = spark.createDataFrame([(1, 2), (3, 4), (1, 1)], ["col1", "col2"])
new_df = df.groupby().apply(modify_df) # You must modify function call to be a select and not an apply
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1078¶
Mensagem: O argumento da função pyspark.context.SparkContext.setLogLevel não é um valor literal e, portanto, não pôde ser avaliado
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.context.SparkContext.setLogLevel com um argumento que não é um valor literal, por exemplo, quando o argumento é uma variável.
O SMA faz uma análise estática do seu código-fonte e, portanto, não é possível avaliar o conteúdo desse argumento e determinar um equivalente no Snowpark.
Cenário¶
Entrada
Neste exemplo, o logLevel é definido na variável my_log_level e, em seguida, my_log_level é usado como parâmetro pelo método setLogLevel.
my_log_level = "WARN"
sparkSession.sparkContext.setLogLevel(my_log_level)
Saída
O SMA não consegue avaliar o argumento do parâmetro de nível de registro, portanto, o EWI SPRKPY1078 é adicionado sobre a linha do registro transformado:
my_log_level = "WARN"
#EWI: SPRKPY1078 => my_log_level is not a literal value and therefore could not be evaluated. Make sure the value of my_log_level is a valid level in Snowpark. Valid log levels are: logging.CRITICAL, logging.DEBUG, logging.ERROR, logging.INFO, logging.NOTSET, logging.WARNING
logging.basicConfig(stream = sys.stdout, level = my_log_level)
Correção recomendada
Mesmo que o SMA não tenha conseguido avaliar o argumento, ele transformará a função pyspark.context.SparkContext.setLogLevel
no equivalente do Snowpark. Certifique-se de que o valor do argumento level
no código de saída gerado seja um nível de registro válido e equivalente no Snowpark, de acordo com a tabela abaixo:
Nível de registro do PySpark |
Nível de registro do Snowpark equivalente |
---|---|
ALL |
logging.NOTSET |
DEBUG |
logging.DEBUG |
ERROR |
logging.ERROR |
FATAL |
logging.CRITICAL |
INFO |
logging.INFO |
OFF |
logging.WARNING |
TRACE |
logging.NOTSET |
WARN |
logging.WARNING |
Assim, a correção recomendada será semelhante:
my_log_level = logging.WARNING
logging.basicConfig(stream = sys.stdout, level = my_log_level)
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1029¶
Mensagem: Esse problema aparece quando a ferramenta detecta o uso do pyspark.sql.readwriter.DataFrameReader.parquet. Essa função é compatível, mas algumas das diferenças entre o Snowpark e o Spark API podem exigir algumas alterações manuais.
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.sql.readwriter.DataFrameReader.parquet. Essa função é compatível com o Snowpark, mas há algumas diferenças que exigiriam algumas alterações manuais.
Cenário¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.readwriter.DataFrameReader.parquet
que gera essa função EWI.
file_paths = [
"path/to/your/file1.parquet",
"path/to/your/file2.parquet",
"path/to/your/file3.parquet",
]
df = session.read.parquet(
*file_paths,
mergeSchema="true",
pathGlobFilter="*file*",
recursiveFileLookup="true",
modifiedBefore="2024-12-31T00:00:00",
modifiedAfter="2023-12-31T00:00:00"
)
Saída
O SMA adiciona o EWI SPRKPY1029
ao código de saída para que você saiba que essa função é compatível com o Snowpark, mas requer alguns ajustes manuais. Observe que as opções suportadas pelo Snowpark são transformadas em chamadas de função option
e as que não são suportadas são removidas. Isso é explicado em mais detalhes nas próximas seções.
file_paths = [
"path/to/your/file1.parquet",
"path/to/your/file2.parquet",
"path/to/your/file3.parquet"
]
#EWI: SPRKPY1076 => Some of the included parameters are not supported in the parquet function, the supported ones will be added into a option method.
#EWI: SPRKPY1029 => This issue appears when the tool detects the usage of pyspark.sql.readwriter.DataFrameReader.parquet. This function is supported, but some of the differences between Snowpark and the Spark API might require making some manual changes.
df = session.read.option("PATTERN", "*file*").parquet(
*file_paths
)
Correção recomendada
Nesta seção, explicamos como configurar os parâmetros paths
e options
para fazê-los funcionar no Snowpark.
1. parâmetro paths
No Spark, esse parâmetro pode ser estar no local ou na nuvem. O Snowpark só aceita locais de nuvem que usam um estágio de snowflake. Assim, você pode criar um estágio temporal e adicionar cada arquivo a ele usando o prefixo file://
.
2. parâmetro options
O Snowpark não permite definir as diferentes options como parâmetros da função parquet
. Como solução alternativa, use as funções option ou options para especificar esses parâmetros como opções extras do DataFrameReader.
Observe que options do Snowpark não são exatamente iguais a options do PySpark, portanto, pode ser necessário fazer algumas alterações manuais. Veja a seguir uma explicação mais detalhada de como configurar as opções mais comuns do PySpark no Snowpark.
2.1 opção mergeSchema
O Parquet suporta a evolução do esquema, permitindo que os usuários comecem com um esquema simples e adicionem gradualmente mais colunas, conforme necessário. Isso pode resultar em vários arquivos de parquet com esquemas diferentes, mas compatíveis. No Snowflake, graças aos recursos infer_schema, você não precisa fazer isso e, portanto, a opção mergeSchema
pode ser simplesmente removida.
2.2 opção pathGlobFilter
Se quiser carregar apenas um subconjunto de arquivos do estágio, use a opção pattern
para especificar uma expressão regular que corresponda aos arquivos que deseja carregar. O SMA já automatiza isso, como pode ver no resultado desse cenário.
2.3 opção recursiveFileLookupstr
Essa opção não é suportada pelo Snowpark. A melhor recomendação é usar uma expressão regular como a opção pathGlobFilter
para obter algo semelhante.
2.4 opção modifiedBefore / modifiedAfter
Tenha o mesmo resultado no Snowflake usando as colunas metadata
.
Nota
As seguintes opções não são suportadas pelo Snowpark:
compression
datetimeRebaseMode
int96RebaseMode
mergeSchema
Abaixo está o exemplo completo de como o código de entrada deve ser transformado para que funcione no Snowpark:
from snowflake.snowpark.column import METADATA_FILE_LAST_MODIFIED, METADATA_FILENAME
temp_stage = f'{session.get_fully_qualified_current_schema()}.{_generate_prefix("TEMP_STAGE")}'
session.sql(f'CREATE TEMPORARY STAGE IF NOT EXISTS {temp_stage}')
session.file.put(f"file:///path/to/your/file1.parquet", f"@{temp_stage}")
session.file.put(f"file:///path/to/your/file2.parquet", f"@{temp_stage}")
session.file.put(f"file:///path/to/your/file3.parquet", f"@{temp_stage}")
df = session.read \
.option("PATTERN", ".*file.*") \
.with_metadata(METADATA_FILENAME, METADATA_FILE_LAST_MODIFIED) \
.parquet(temp_stage) \
.where(METADATA_FILE_LAST_MODIFIED < '2024-12-31T00:00:00') \
.where(METADATA_FILE_LAST_MODIFIED > '2023-12-31T00:00:00')
Recomendações adicionais¶
No Snowflake, você pode aproveitar outras abordagens para a ingestão de dados de parquet, como:
Aproveitamento dos recursos nativos de ingestão de parquet. Considere também autoingest com snowpipe
Tabelas externas do Parquet que podem ser apontadas diretamente para locais de arquivos na nuvem.
Usando tabelas Iceberg.
Ao fazer uma migração, é uma boa prática aproveitar os relatórios do SMA para tentar criar um inventário de arquivos e determinar, após a modernização, para quais estágios/tabelas os dados serão mapeados.
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1039¶
Aviso
Este código de problema está obsoleto
Mensagem: pyspark.sql.column.Column.getItem tem uma solução alternativa, consulte a documentação para obter mais informações
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.sql.column.Column.getItem, que tem uma solução alternativa.
Cenário¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.column.Column.getItem
que gera esse EWI. Neste exemplo, a função getItem
é usada para obter um item por posição e por chave.
df = spark.createDataFrame([(1, ["apple", "banana", "orange"]), (2, ["carrot", "avocado", "banana"])], ["id", "fruits"])
df.withColumn("first_fruit", col("fruits").getItem(0))
df = spark.createDataFrame([(1, {"apple": 10, "banana": 20}), (2, {"carrot": 15, "grape": 25}), (3, {"pear": 30, "apple": 35})], ["id", "fruit_quantities"])
df.withColumn("apple_quantity", col("fruit_quantities").getItem("apple"))
Saída
O SMA adiciona o EWI SPRKPY1039
ao código de saída para que você saiba que essa função não é diretamente compatível com o Snowpark, mas tem uma solução alternativa.
df = spark.createDataFrame([(1, ["apple", "banana", "orange"]), (2, ["carrot", "avocado", "banana"])], ["id", "fruits"])
#EWI: SPRKPY1039 => pyspark.sql.column.Column.getItem has a workaround, see documentation for more info
df.withColumn("first_fruit", col("fruits").getItem(0))
df = spark.createDataFrame([(1, {"apple": 10, "banana": 20}), (2, {"carrot": 15, "grape": 25}), (3, {"pear": 30, "apple": 35})], ["id", "fruit_quantities"])
#EWI: SPRKPY1039 => pyspark.sql.column.Column.getItem has a workaround, see documentation for more info
df.withColumn("apple_quantity", col("fruit_quantities").getItem("apple"))
Correção recomendada
Como solução alternativa, você pode usar o operador de indexador de coluna Snowpark com o nome ou a posição do campo como índice.
df = spark.createDataFrame([(1, ["apple", "banana", "orange"]), (2, ["carrot", "avocado", "banana"])], ["id", "fruits"])
df.withColumn("first_fruit", col("fruits")[0])
df = spark.createDataFrame([(1, {"apple": 10, "banana": 20}), (2, {"carrot": 15, "grape": 25}), (3, {"pear": 30, "apple": 35})], ["id", "fruit_quantities"])
df.withColumn("apple_quantity", col("fruit_quantities")["apple"])
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1068¶
Mensagem: toPandas contém colunas do tipo ArrayType que não são suportadas e têm uma solução alternativa.
Categoria: Aviso
Descrição¶
pyspark.sql.DataFrame.toPandas não funciona corretamente se houver colunas do tipo ArrayType. A solução alternativa para esses casos é converter essas colunas em um dicionário Python usando o método json.loads.
Cenário¶
Entrada
ToPandas retorna os dados do DataFrame original como um Pandas DataFrame.
sparkDF = spark.createDataFrame([
Row(a=1, b=2., c='string1', d=date(2000, 1, 1), e=datetime(2000, 1, 1, 12, 0)),
Row(a=2, b=3., c='string2', d=date(2000, 2, 1), e=datetime(2000, 1, 2, 12, 0))
])
pandasDF = sparkDF.toPandas()
Saída
A ferramenta adiciona este EWI para que você saiba que o toPandas não é suportado se houver colunas do tipo ArrayType, mas tem uma solução alternativa.
sparkDF = spark.createDataFrame([
Row(a=1, b=2., c='string1', d=date(2000, 1, 1), e=datetime(2000, 1, 1, 12, 0)),
Row(a=2, b=3., c='string2', d=date(2000, 2, 1), e=datetime(2000, 1, 2, 12, 0))
])
#EWI: SPRKPY1068 => toPandas doesn't work properly If there are columns of type ArrayType. The workaround for these cases is converting those columns into a Python Dictionary by using json.loads method. example: df[colName] = json.loads(df[colName]).
pandasDF = sparkDF.toPandas()
Correção recomendada
pandas_df = sparkDF.toPandas()
## check/convert all resulting fields from calling toPandas when they are of
## type ArrayType,
## they will be reasigned by converting them into a Python Dictionary
## using json.loads method
for field in pandas_df.schema.fields:
if isinstance(field.datatype, ArrayType):
pandas_df[field.name] = pandas_df[field.name].apply(lambda x: json.loads(x) if x is not None else x)
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1048¶
Aviso
Esse código de problema foi depreciado desde o Spark Conversion Core Version 2.4.0
Mensagem: pyspark.sql.session.SparkSession.conf tem uma solução alternativa
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.session.SparkSession.conf que tem uma solução alternativa.
Cenário¶
Entrada
Veja a seguir um exemplo de como definir uma configuração na propriedade conf
.
spark.conf.set("spark.sql.crossJoin.enabled", "true")
Saída
A ferramenta adiciona o EWI SPRKPY1048
indicando que uma solução alternativa pode ser implementada.
#EWI: SPRKPY1048 => pyspark.sql.session.SparkSession.conf has a workaround, see documentation for more info
spark.conf.set("spark.sql.crossJoin.enabled", "true")
Correção recomendada
SparkSession.conf é usado para passar algumas configurações específicas usadas apenas pelo Pyspark e não se aplica ao Snowpark. Você pode remover ou comentar o código
#spark.conf.set("spark.sql.crossJoin.enabled", "true")
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1019¶
Aviso
Esse código de problema foi depreciado desde o Spark Conversion Core Version 4.8.0
Mensagem: pyspark.sql.functions.datediff tem uma solução alternativa
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.functions.datediff, que tem uma solução alternativa.
Cenário¶
Entrada
Neste exemplo, usamos o datediff para calcular a diferença de dia entre «today» e outras datas.
contacts = (contacts
#days since last event
.withColumn('daysSinceLastEvent', datediff(lit(today),'lastEvent'))
#days since deployment
.withColumn('daysSinceLastDeployment', datediff(lit(today),'lastDeploymentEnd'))
#days since online training
.withColumn('daysSinceLastTraining', datediff(lit(today),'lastTraining'))
#days since last RC login
.withColumn('daysSinceLastRollCallLogin', datediff(lit(today),'adx_identity_lastsuccessfullogin'))
#days since last EMS login
.withColumn('daysSinceLastEMSLogin', datediff(lit(today),'vms_lastuserlogin'))
)
Saída
O SMA retorna o EWI SPRKPY1019 sobre a linha em que datediff é usado, para que você possa identificar onde corrigir.
from pyspark.sql.functions import datediff
#EWI: SPRKPY1019 => pyspark.sql.functions.datediff has a workaround, see documentation for more info
contacts = (contacts
#days since last event
.withColumn('daysSinceLastEvent', datediff(lit(today),'lastEvent'))
#days since deployment
.withColumn('daysSinceLastDeployment', datediff(lit(today),'lastDeploymentEnd'))
#days since online training
.withColumn('daysSinceLastTraining', datediff(lit(today),'lastTraining'))
#days since last RC login
.withColumn('daysSinceLastRollCallLogin', datediff(lit(today),'adx_identity_lastsuccessfullogin'))
#days since last EMS login
.withColumn('daysSinceLastEMSLogin', datediff(lit(today),'vms_lastuserlogin'))
)
O SMA converte pyspark.sql.functions.datediff em snowflake.snowpark.functions.daydiff, que também calcula a diferença de dias entre duas datas.
Correção recomendada
datediff(part: string ,end: ColumnOrName, start: ColumnOrName)
Ação: Importar snowflake.snowpark.functions, que contém uma implementação da função datediff que requer um parâmetro extra para a parte de data e hora e permite mais versatilidade no cálculo de diferenças entre datas.
from snowflake.snowpark import Session
from snowflake.snowpark.functions import datediff
contacts = (contacts
#days since last event
.withColumn('daysSinceLastEvent', datediff('day', lit(today),'lastEvent'))
#days since deployment
.withColumn('daysSinceLastDeployment', datediff('day',lit(today),'lastDeploymentEnd'))
#days since online training
.withColumn('daysSinceLastTraining', datediff('day', lit(today),'lastTraining'))
#days since last RC login
.withColumn('daysSinceLastRollCallLogin', datediff('day', lit(today),'adx_identity_lastsuccessfullogin'))
#days since last EMS login
.withColumn('daysSinceLastEMSLogin', datediff('day', lit(today),'vms_lastuserlogin'))
)
Recomendação¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1009¶
Message : pyspark.sql.dataframe.DataFrame.approxQuantile tem uma solução alternativa
Category : Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.dataframe.DataFrame.approxQuantile que tem uma solução alternativa.
Cenário¶
Entrada
É importante entender que o Pyspark usa duas funções approxQuantile diferentes. Aqui, usamos a versão DataFrame approxQuantile
from pyspark.sql import SparkSession
spark = SparkSession.builder.getOrCreate()
data = [['Sun', 10],
['Mon', 64],
['Thr', 12],
['Wen', 15],
['Thu', 68],
['Fri', 14],
['Sat', 13]]
columns = ['Day', 'Ammount']
df = spark.createDataFrame(data, columns)
df.approxQuantile('Ammount', [0.25, 0.5, 0.75], 0)
Saída
O SMA retorna o EWI SPRKPY1009 sobre a linha em que approxQuantile é usado, para que você possa identificar onde corrigir.
from snowflake.snowpark import Session
spark = Session.builder.getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":0,"minor":0,"patch":0},"attributes":{"language":"Python"}})
data = [['Sun', 10],
['Mon', 64],
['Thr', 12],
['Wen', 15],
['Thu', 68],
['Fri', 14],
['Sat', 13]]
columns = ['Day', 'Ammount']
df = spark.createDataFrame(data, columns)
#EWI: SPRKPY1009 => pyspark.sql.dataframe.DataFrame.approxQuantile has a workaround, see documentation for more info
df.approxQuantile('Ammount', [0.25, 0.5, 0.75], 0)
Correção recomendada
Use o método aproxQuantile do Snowpark. Alguns parâmetros não correspondem, e por isso exigem ajustes manuais. Para o exemplo do código de saída, uma correção recomendada poderia ser:
from snowflake.snowpark import Session
...
df = spark.createDataFrame(data, columns)
df.stat.approx_quantile('Ammount', [0.25, 0.5, 0.75])
pyspark.sql.dataframe.DataFrame.approxQuantile relativeError parameter não existe no SnowPark.
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1058¶
Mensagem: < método > com < chave > Não há suporte para a chave específica da plataforma.
Categoria: ConversionError
Descrição¶
Os métodos get
e set
do pyspark.sql.conf.RuntimeConfig não são compatíveis com uma chave específica da plataforma.
Cenários¶
Nem todos os usos dos métodos get
ou set
terão um EWI no código de saída. Esse EWI aparece quando a ferramenta detecta o uso desses métodos com uma chave específica da plataforma que não é compatível.
Cenário 1¶
Entrada
Veja a seguir um exemplo dos métodos get
ou set
com chaves compatíveis no Snowpark.
session.conf.set("use_constant_subquery_alias", False)
spark.conf.set("sql_simplifier_enabled", True)
session.conf.get("use_constant_subquery_alias")
session.conf.get("use_constant_subquery_alias")
Saída
Como as chaves são compatíveis com o Snowpark, a ferramenta não adiciona o EWI no código de saída.
session.conf.set("use_constant_subquery_alias", True)
session.conf.set("sql_simplifier_enabled", False)
session.conf.get("use_constant_subquery_alias")
session.conf.get("sql_simplifier_enabled")
Correção recomendada
Não há nenhuma correção recomendada para esse cenário.
Cenário 2¶
Entrada
Abaixo está um exemplo usando chaves não suportadas.
data =
[
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
session.conf.set("spark.sql.shuffle.partitions", "50")
spark.conf.set("spark.yarn.am.memory", "1g")
session.conf.get("spark.sql.shuffle.partitions")
session = spark.conf.get("spark.yarn.am.memory")
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
Saída
A ferramenta adiciona esse EWI SPRKPY1058
no código de saída para que você saiba que esses métodos não são compatíveis com uma chave específica da plataforma.
data =
[
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
#EWI: SPRKPY1058 => pyspark.sql.conf.RuntimeConfig.set method with this "spark.sql.shuffle.partitions" Platform specific key is not supported.
spark.conf.set("spark.sql.shuffle.partitions", "50")
#EWI: SPRKPY1058 => pyspark.sql.conf.RuntimeConfig.set method with this "spark.yarn.am.memory" Platform specific key is not supported.
spark.conf.set("spark.yarn.am.memory", "1g")
#EWI: SPRKPY1058 => pyspark.sql.conf.RuntimeConfig.get method with this "spark.sql.shuffle.partitions" Platform specific key is not supported.
spark.conf.get("spark.sql.shuffle.partitions")
#EWI: SPRKPY1058 => pyspark.sql.conf.RuntimeConfig.get method with this "spark.yarn.am.memory" Platform specific key is not supported.
spark.conf.get("spark.yarn.am.memory")
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
Correção recomendada
A correção recomendada é remover esses métodos.
data =
[
("John", 30, "New York"),
("Jane", 25, "San Francisco")
]
df = spark.createDataFrame(data, schema=["Name", "Age", "City"])
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1049¶
Aviso
Esse código de problema foi descontinuado desde o Spark Conversion Core Version 2.1.9
Mensagem: pyspark.sql.session.SparkSession.sparkContext tem uma solução alternativa
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.session.SparkSession. sparkContext que tem uma solução alternativa.
Cenário¶
Entrada
Abaixo está um exemplo que cria uma sessão spark e, em seguida, usa a propriedade SparkContext
para imprimir o appName.
print("APP Name :"+spark.sparkContext.appName())
Saída
A ferramenta adiciona o EWI SPRKPY1049
indicando que uma solução alternativa pode ser implementada.
#EWI: SPRKPY1049 => pyspark.sql.session.SparkSession.sparkContext has a workaround, see documentation for more info
print("APP Name :"+spark.sparkContext.appName())
Correção recomendada
O SparkContext não é compatível com SnowPark, mas você pode acessar os métodos e as propriedades de SparkContext diretamente da instância Session.
## Pyspark
print("APP Name :"+spark.sparkContext.appName())
can be used in SnowPark removing the sparkContext as:
#Manual adjustment in SnowPark
print("APP Name :"+spark.appName());
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1018¶
Aviso
Esse código de problema foi depreciado desde o Spark Conversion Core Version 4.8.0
Mensagem: pyspark.sql.functions.date_sub tem uma solução alternativa
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso de pyspark.sql.functions.date_sub, que tem uma solução alternativa.
Cenário¶
Entrada
Neste exemplo, usamos date_add para calcular a data 5 dias antes da data atual para o dataframe df.
col = df.select(date_sub(df.colName, 5))
Saída
O SMA retorna o EWI SPRKPY1018 sobre a linha em que date_sub é usado, para que você possa identificar onde corrigir.
#EWI: SPRKPY1018 => pyspark.sql.functions.date_sub has a workaround, see documentation for more info
col = df.select(date_sub(df.colName, 5))
Correção recomendada
Importar snowflake.snowpark.functions, que contém uma implementação para a função date_sub.
from pyspark.sql.functions import date_sub
df.withColumn("date", date_sub(df.colName, 5))
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1008¶
Mensagem: pyspark.sql.context.HiveContext não é necessário
Categoria: Aviso.
Descrição¶
Esse problema aparece quando a ferramenta detecta o uso do pyspark.sql.context.HiveContext, que não é necessário.
Cenário¶
Entrada
Este é um exemplo para criar uma conexão com um armazenamento do Hive.
from pyspark.sql import HiveContext
hive_context = HiveContext(sc)
df = hive_context.table("myTable")
df.show()
Saída
No Snowflake, não há Hive stores, portanto, o Hive Context não é necessário. Mesmo assim, você pode usar arquivos parquet no Snowflake; consulte este tutorial para saber como.
#EWI: SPRKPY1008 => pyspark.sql.context.HiveContext is not required
hive_context = sc
df = hive_context.table("myTable")
df.show()
a variável sc refere-se a um objeto de sessão do Snow Park
Correção recomendada
Para o código de saída no exemplo, você deve adicionar o objeto de sessão do Snow Park de forma semelhante a este código:
## Here manually we can add the Snowpark Session object via a json config file called connection.json
import json
from snowflake.snowpark import Session
jsonFile = open("connection.json")
connection_parameter = json.load(jsonFile)
jsonFile.close()
sc = Session.builder.configs(connection_parameter).getOrCreate()
hive_context = sc
df = hive_context.table("myTable")
df.show()
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1059¶
Aviso
Esse código de problema foi depreciado desde o Spark Conversion Core Version 2.45.1
Mensagem: pyspark.storagelevel.StorageLevel tem uma solução alternativa, consulte a documentação.
Categoria: Aviso
Descrição¶
Atualmente, o uso do StorageLevel não é necessário no Snowpark, pois a Snowflake controla o armazenamento. Para obter mais informações, consulte o EWI SPRKPY1072
Recomendações adicionais¶
Atualize seu aplicativo para a versão mais recente.
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1079¶
Mensagem: O argumento da função pyspark.context.SparkContext.setLogLevel não é um nível de registro PySpark válido
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.context.SparkContext.setLogLevel com um argumento que não é um nível de registro válido no PySpark e, portanto, não foi possível determinar um equivalente no Snowpark.
Cenário¶
Entrada
aqui o nível de registro usa «INVALID_LOG_LEVEL», que não é um nível de registro válido do Pyspark.
sparkSession.sparkContext.setLogLevel("INVALID_LOG_LEVEL")
Saída
O SMA não consegue reconhecer o nível de registro «INVALID_LOG_LEVEL», embora o SMA faça a conversão, o EWI SPRKPY1079 é adicionado para indicar um possível problema.
#EWI: SPRKPY1079 => INVALID_LOG_LEVEL is not a valid PySpark log level, therefore an equivalent could not be determined in Snowpark. Valid PySpark log levels are: ALL, DEBUG, ERROR, FATAL, INFO, OFF, TRACE, WARN
logging.basicConfig(stream = sys.stdout, level = logging.INVALID_LOG_LEVEL)
Correção recomendada
Certifique-se de que o nível de registro usado na função pyspark.context.SparkContext.setLogLevel seja um nível de registro válido no PySpark ou no Snowpark e tente novamente.
logging.basicConfig(stream = sys.stdout, level = logging.DEBUG)
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1028¶
Mensagem: pyspark.sql.readwriter.DataFrameReader.orc tem uma solução alternativa, consulte a documentação para obter mais informações
Categoria: Aviso
Descrição¶
Esse problema aparece quando o SMA detecta o uso da função pyspark.sql.readwriter.DataFrameReader.orc, que tem uma solução alternativa.
Cenário¶
Entrada
Veja a seguir um exemplo de uso da função pyspark.sql.readwriter.DataFrameReader.orc
que gera esse EWI. Neste exemplo, a função orc
é usada para ler vários arquivos .orc
e usa algumas opções extras, como mergeSchema e recursiveFileLookup para ajustar o comportamento da leitura dos arquivos.
file_paths = [
"path/to/your/file1.orc",
"path/to/your/file2.orc",
"path/to/your/file3.orc",
]
df = session.read.orc(
file_paths,
mergeSchema="True",
recursiveFileLookup="True"
)
Saída
O SMA adiciona o EWI SPRKPY1028
ao código de saída para que você saiba que essa função não é diretamente compatível com o Snowpark, mas tem uma solução alternativa.
file_paths = [
"path/to/your/file1.orc",
"path/to/your/file2.orc",
"path/to/your/file3.orc",
]
#EWI: SPRKPY1028 => pyspark.sql.readwriter.DataFrameReader.orc has a workaround, see documentation for more info
df = session.read.orc(
file_paths,
mergeSchema="True",
recursiveFileLookup="True"
)
Correção recomendada
Nesta seção, explicamos como configurar o parâmetro path
e as options
extras para que funcionem no Snowpark.
1. parâmetro path
O Snowpark exige que o parâmetro path seja um local de estágio, portanto, como solução alternativa, você pode criar um estágio temporário e adicionar cada arquivo .orc
a esse estágio usando o prefixo file://
.
2. parâmetros options
O Snowpark não permite definir as opções extras como parâmetros da função orc
. Como solução alternativa, para muitos deles, você pode usar a função snowflake.snowpark.DataFrameReader.option para especificar esses parâmetros como opções do DataFrameReader.
Nota
As seguintes opções não são suportadas pelo Snowpark:
compression
mergeSchema
Abaixo está o exemplo completo de como o código de entrada deve ficar depois de aplicar as sugestões mencionadas acima para fazê-lo funcionar no Snowpark:
stage = f'{session.get_fully_qualified_current_schema()}.{_generate_prefix("TEMP_STAGE")}'
session.sql(f'CREATE TEMPORARY STAGE IF NOT EXISTS {stage}')
session.file.put(f"file:///path/to/your/file1.orc", f"@{stage}")
session.file.put(f"file:///path/to/your/file2.orc", f"@{stage}")
session.file.put(f"file:///path/to/your/file3.orc", f"@{stage}")
df = session.read.option(recursiveFileLookup, "True").orc(stage)
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1038¶
Mensagem: _ spark element _ is not yet recognized
Categoria: Erro de conversão
Descrição¶
Esse problema aparece quando há um elemento PySpark em seu código-fonte que não foi reconhecido pelo SMA. Isso pode ocorrer por diferentes motivos, como:
Um elemento que não existe em PySpark.
Um elemento que foi adicionado em uma versão do PySpark que o SMA ainda não suporta.
Um erro interno do SMA ao processar o elemento.
Esse é um código de erro genérico usado pelo SMA para qualquer elemento não reconhecido.
Cenário¶
Entrada
Abaixo está um exemplo de uso de uma função que não pôde ser reconhecida pelo SMA porque ela não existe em PySpark.
from pyspark.sql import functions as F
F.unrecognized_function()
Saída
O SMA adiciona o EWI SPRKPY1038
ao código de saída para informar que esse elemento não pôde ser reconhecido.
from snowflake.snowpark import functions as F
#EWI: SPRKPY1038 => pyspark.sql.functions.non_existent_function is not yet recognized
F.unrecognized_function()
Correção recomendada
Para tentar identificar o problema, você pode realizar as seguintes validações:
Verificar se o elemento existe em PySpark.
Verifique se o elemento está escrito corretamente.
Verifique se está usando uma versão do PySpark compatível com o SMA. Para saber qual versão do PySpark é compatível com o SMA no momento da execução do SMA, examine a primeira página do arquivo
DetailedReport.docx
.
Se for um elemento válido do PySpark, informe que encontrou um erro de conversão nesse elemento específico usando a opção de Relatar um problema do SMA e inclua qualquer informação adicional que considere útil.
Observe que, se um elemento não puder ser reconhecido pelo SMA, isso não significa que ele não seja compatível com o Snowpark. Consulte a documentação do Snowpark para verificar se existe um elemento equivalente.
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.
SPRKPY1069¶
Mensagem: Se o parâmetro partitionBy for uma lista, o Snowpark lançará um erro.
Categoria: Aviso
Descrição¶
Quando há um uso do método pyspark.sql.readwriter.DataFrameWriter.parquet em que se trata do parâmetro partitionBy
, a ferramenta mostra o EWI.
Isso ocorre porque, no Snowpark, o DataFrameWriter.parquet suporta apenas um ColumnOrSqlExpr
como parâmetro partitionBy.
Cenários¶
Cenário 1¶
Código de entrada:
Para esse cenário, o parâmetro partitionBy não é uma lista.
df = spark.createDataFrame([(25, "Alice", "150"), (30, "Bob", "350")], schema=["age", "name", "value"])
df.write.parquet(file_path, partitionBy="age")
Código de saída:
A ferramenta adiciona o EWI SPRKPY1069
para que você saiba que o Snowpark gera um erro se o parâmetro for uma lista.
df = spark.createDataFrame([(25, "Alice", "150"), (30, "Bob", "350")], schema=["age", "name", "value"])
#EWI: SPRKPY1069 => If partitionBy parameter is a list, Snowpark will throw and error.
df.write.parquet(file_path, partition_by = "age", format_type_options = dict(compression = "None"))
Correção recomendada
Não há uma correção recomendada para esse cenário porque a ferramenta sempre adiciona esse EWI apenas para o caso de o parâmetro partitionBy ser uma lista. Lembre-se de que, no Snowpark, só são aceitos locais de nuvem que usem um estágio de snowflake.
df = spark.createDataFrame([(25, "Alice", "150"), (30, "Bob", "350")], schema=["age", "name", "value"])
stage = f'{Session.get_fully_qualified_current_schema()}.{_generate_prefix("TEMP_STAGE")}'
Session.sql(f'CREATE TEMPORARY STAGE IF NOT EXISTS {stage}').show()
Session.file.put(f"file:///path/to/data/file.parquet", f"@{stage}")
df.write.parquet(stage, partition_by = "age", format_type_options = dict(compression = "None"))
Cenário 2¶
Código de entrada:
Para esse cenário, o parâmetro partitionBy é uma lista.
df = spark.createDataFrame([(25, "Alice", "150"), (30, "Bob", "350")], schema=["age", "name", "value"])
df.write.parquet(file_path, partitionBy=["age", "name"])
Código de saída:
A ferramenta adiciona o EWI SPRKPY1069
para que você saiba que o Snowpark gera um erro se o parâmetro for uma lista.
df = spark.createDataFrame([(25, "Alice", "150"), (30, "Bob", "350")], schema=["age", "name", "value"])
#EWI: SPRKPY1069 => If partitionBy parameter is a list, Snowpark will throw and error.
df.write.parquet(file_path, partition_by = ["age", "name"], format_type_options = dict(compression = "None"))
Correção recomendada
Se o valor do parâmetro for uma lista
, substitua-o por um ColumnOrSqlExpr
.
df.write.parquet(file_path, partition_by = sql_expr("age || name"), format_type_options = dict(compression = "None"))
Recomendações adicionais¶
Para obter mais suporte, envie um e-mail para sma-support@snowflake.com ou publique um problema no SMA.