Snowpark Migration Accelerator: Python용 코드 발행

SPRKPY1000

메시지: 소스 프로젝트 Spark-core 버전은 xx.xx:xx.x.x이고, Snowpark에서 지원하는 Spark-core 버전은 2.12:3.1.2이므로 기존 매핑과 함수 차이가 있을 수 있습니다.

카테고리: 경고.

설명

이 문제는 소스 코드의 Pyspark 버전이 지원되지 않을 때 표시됩니다. 즉, 기존 매핑 간에 기능적인 차이가 있을 수 있습니다.

추가 권장 사항

  • SMA 가 Snowpark와의 호환성을 위해 검사한 pyspark 버전은 2.12에서 3.1.2입니다. 이 범위를 벗어난 버전을 사용하는 경우 도구에서 일관성 없는 결과가 나올 수 있습니다. 스캔하는 소스 코드의 버전을 변경할 수 있습니다.

  • For more support, you can email us at sma-support@snowflake.com or post an issue in the SMA.

SPRKPY1001

Message**:** This code section has parsing errors

Category**:** Parsing error.

설명

구문 분석 오류는 파일의 코드를 올바르게 읽거나 이해할 수 없는 경우(파일을 올바르게 “구문 분석”할 수 없는 경우) Snowpark Migration Accelerator(SMA)에서 보고합니다. 이 문제 코드는 파일에 1개 이상의 구문 분석 오류가 있을 때 표시됩니다.

시나리오

입력: 예를 들어, 코드에 잘못된 구문이 있는 경우 EWI 메시지가 표시됩니다.

def foo():
    x = %%%%%%1###1

출력: SMA 구문 분석 오류를 찾아 해당 EWI 메시지를 추가하여 구문 분석 오류를 설명합니다.

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

추가 권장 사항

  • Check that the file contains valid Python code. (You can use the issues.csv file to find all files with this EWI code to determine which file(s) were not processed by the tool due to parsing error(s).) Many parsing errors occur because only part of the code is input into the tool, so it’s bets to ensure that the code will run in the source. If it is valid, report that you encountered a parsing error using the Report an Issue option in the SMA. Include the line of code that was causing a parsing error in the description when you file this issue.

  • For more support, you can email us at sma-support@snowflake.com or post an issue in the SMA.

SPRKPY1002

Message**:** < element > is not supported,Spark element is not supported.

Category**:** Conversion error.

설명

이 문제는 도구가 Snowpark에서 지원되지 않는 요소의 사용을 감지하고 이와 관련된 자체 오류 코드가 없을 때 표시됩니다. 지원되지 않는 요소에 대해 SMA 에서 사용하는 일반적인 오류 코드입니다.

추가 권장 사항

  • 메시지의 옵션이나 요소가 지원되지 않는다고 해서 해결 방법을 찾을 수 없다는 의미는 아닙니다. 도구 자체에서 해결책을 찾을 수 없다는 의미일 뿐입니다.

  • Pyspark.ml 라이브러리에서 지원되지 않는 요소를 발견한 경우 몇 가지 다른 접근법을 고려해 보십시오. Snowflake에서 제공하는 이 가이드와 같이 ml과 관련된 문제를 해결하는 데 사용할 수 있는 추가 가이드가 있습니다.

  • 소스 코드에 올바른 구문이 있는지 확인합니다. (issues.csv 파일을 사용하여 변환 오류가 발생하는 위치를 확인할 수 있습니다.) 구문이 올바른 경우 SMA 에서 문제 신고 옵션을 사용하여 특정 요소에서 변환 오류가 발생했음을 신고하십시오. 이 문제를 파일로 제출할 때 설명에 오류를 일으킨 코드 라인을 포함하십시오.

  • For more support, you can email us at sma-support@snowflake.com or post an issue in the SMA.

SPRKPY1003

Message**:** An error occurred when loading the symbol table.

Category**:** Conversion error.

설명

이 문제는 기호 테이블에서 기호를 처리하는 데 오류가 있을 때 표시됩니다. 기호 테이블은 SMA 의 기본 아키텍처의 일부로, 보다 복잡한 변환을 가능하게 합니다. 이 오류는 소스 코드에 예기치 않은 문이 있기 때문일 수 있습니다.

추가 권장 사항

  • This is unlikely to be an error in the source code itself, but rather is an error in how the tool processes the source code. The best resolution would be to post an issue in the SMA.

  • For more support, you can email us at sma-support@snowflake.com or post an issue in the SMA.

SPRKPY1004

Message**:** The symbol table could not be loaded.

Category**:** Parsing error.

설명

이 문제는 도구 실행 과정에서 예기치 않은 오류가 발생했을 때 표시됩니다. 기호 테이블을 로딩할 수 없으므로 도구에서 평가 또는 변환 프로세스를 시작할 수 없습니다.

추가 권장 사항

SPRKPY1005

경고

This issue code has been deprecated since Spark Conversion Core Version 4.8.0

Message**:** pyspark.conf.SparkConf is not required

Category**:** Warning.

설명

This issue appears when the tool detects the usage of pyspark.conf.SparkConf which is not required.

시나리오

입력

SparkConf 는 매개 변수 없이 또는 loadDefaults와 함께 호출할 수 있습니다.

from pyspark import SparkConf

my_conf = SparkConf(loadDefaults=True)

출력

For both cases (with or without parameters) SMA creates a Snowpark Session.builder object:

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

추가 권장 사항

  • 불필요한 매개 변수가 제거되고 경고 설명이 삽입됩니다. 사용자의 추가 작업은 없어야 합니다.

  • For more support, you can email us at sma-support@snowflake.com or post an issue in the SMA.

SPRKPY1006

경고

This issue code has been deprecated since Spark Conversion Core Version 4.8.0

Message**:** pyspark.context.SparkContext is not required

Category**:** Warning.

설명

This issue appears when the tool detects the usage of pyspark.context.SparkContext, which is not required in Snowflake.

시나리오

입력

이 예제에서는 Spark 클러스터에 대한 연결을 생성하는 두 가지 컨텍스트가 있습니다

from pyspark import SparkContext

sql_context1 = SparkContext(my_sc1)
sql_context2 = SparkContext(sparkContext=my_sc2)

출력

Snowflake에는 클러스터링이 없어 컨텍스트가 필요하지 않으므로 Spark 속성을 포함하는 my_sc1 및 my_sc2 변수는 필요하지 않거나 코드를 수정하기 위해 조정해야 할 수 있습니다.

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

추가 권장 사항

  • 불필요한 매개 변수가 제거되고 경고 설명이 삽입됩니다. 사용자의 작업이 없어야 합니다.

  • For more support, you can email us at sma-support@snowflake.com or post an issue in the SMA.

SPRKPY1007

경고

This issue code has been deprecated since Spark Conversion Core Version 4.8.0

Message**:** pyspark.sql.context.SQLContext is not required

Category**:** Warning.

설명

This issue appears when the tool detects the usage of pyspark.sql.context.SQLContext, which is not required.

시나리오

입력

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

출력

출력 코드는 pyspark.SQLContext 에 대한 라인을 설명하고 시나리오를 구성에 대한 참조로 대체합니다. Spark 속성이 포함된 my_sc1 및 my_sc2 변수는 필수가 아니거나 코드를 수정하기 위해 변경해야 할 수 있습니다.

#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

추가 권장 사항

  • 이는 불필요한 매개 변수이며 소스 코드에 경고 설명이 삽입되어 제거됩니다. 사용자의 작업이 없어야 합니다.

  • For more support, you can email us at sma-support@snowflake.com or post an issue in the SMA.

SPRKPY1008

메시지: pyspark.sql.context.HiveContext 는 필수가 아닙니다

카테고리: 경고.

설명

This issue appears when the tool detects the usage of pyspark.sql.context.HiveContext, which is not required.

시나리오

입력

이 예제에서는 Hive 스토어에 대한 연결을 생성하는 예제입니다.

from pyspark.sql import HiveContext
hive_context = HiveContext(sc)
df = hive_context.table("myTable")
df.show()

출력

In Snowflake there are not Hive stores, so the Hive Context is not required, You can still use parquet files on Snowflake please check this tutorial to learn how.

#EWI: SPRKPY1008 => pyspark.sql.context.HiveContext is not required
hive_context = sc
df = hive_context.table("myTable")
df.show()

the sc variable refers to a Snow Park Session Object

권장 수정

For the output code in the example you should add the Snow Park Session Object similar to this code:

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

추가 권장 사항

SPRKPY1009

Message**:** pyspark.sql.dataframe.DataFrame.approxQuantile has a workaround

Category**:** Warning.

설명

This issue appears when the tool detects the usage of pyspark.sql.dataframe.DataFrame.approxQuantile which has a workaround.

시나리오

입력

It’s important understand that Pyspark uses two different approxQuantile functions, here we use the DataFrame approxQuantile version

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)

출력

SMA 는 접근 사분위수가 사용되는 라인 위에 EWI SPRKPY1009 을 반환하므로 수정할 위치를 식별하는 데 사용할 수 있습니다.

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)

권장 수정

Use Snowpark approxQuantile method. Some parameters don’t match so they require some manual adjustments. for the output code’s example a recommended fix could be:

from snowflake.snowpark import Session
...
df = spark.createDataFrame(data, columns)

df.stat.approx_quantile('Ammount', [0.25, 0.5, 0.75])

SnowPark 에는 DataFrame.approxQuantile의 상대 오류 매개 변수가 존재하지 않습니다.

추가 권장 사항

SPRKPY1010

메시지: pyspark.sql.dataframe.DataFrame.checkpoint에 해결 방법이 있습니다

카테고리: 경고.

설명

This issue appears when the tool detects the usage of pyspark.sql.dataframe.DataFrame.checkpoint which has a workaround.

시나리오

입력

PySpark 에서 체크포인트는 데이터프레임의 논리적 계획을 잘라내는 데 사용되며, 이는 논리적 계획이 커지는 것을 방지하기 위한 것입니다.

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)

출력

SMA returns the EWI SPRKPY1010 over the line where approxQuantile is used, so you can use to identify where to fix. Note that also marks the setCheckpointDir as unsupported, but a checpointed directory is not required for the fix.

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)

권장 수정

Snowpark를 사용하면 명시적 체크포인트가 필요하지 않습니다.Snowpark는 SQL 기반 작업과 함께 작동하므로 Snowflake 쿼리 최적화 엔진에 의해 최적화되어 불필요한 계산이나 제어할 수 없는 논리적 계획이 필요하지 않습니다.

However there could be scenarios where you would require persist the result of a computation on a dataframe. In this scenarios you can save materialize the results by writing the dataframe on a Snowflake Table or in a Snowflake Temporary Table.

  • 영구 테이블을 사용하거나 세션 종료 후에도 언제든지 계산된 결과에 액세스할 수 있습니다.

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"
  • 다른 수정 방법인 임시 테이블을 사용하면 세션이 종료된 후 테이블이 삭제된다는 장점이 있습니다.

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"

추가 권장 사항

SPRKPY1011

메시지: pyspark.sql.dataframe.DataFrameStatFunctions.approxQuantile에는 해결 방법이 있습니다

카테고리: 경고.

설명

This issue appears when the tool detects the usage of pyspark.sql.dataframe.DataFrameStatFunctions.approxQuantile which has a workaround.

시나리오

입력

It’s important understand that Pyspark uses two different approxQuantile functions, here we use the DataFrameStatFunctions approxQuantile version.

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)

출력

SMA 는 접근 사분위수가 사용되는 라인 위에 EWI SPRKPY1011 을 반환하므로 수정할 위치를 식별하는 데 사용할 수 있습니다.

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)

권장 수정

You can use Snowpark approxQuantile method. Some parameters don’t match so they require some manual adjustments. for the output code’s example a recommended fix could be:

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

SnowPark 에는 DataFrame.approxQuantile의 상대 오류 매개 변수가 존재하지 않습니다.

추가 권장 사항

SPRKPY1012

경고

이 문제 코드는 사용 중단 되었습니다

메시지: pyspark.sql.dataframe.DataFrameStatFunctions.writeTo에 해결 방법이 있습니다

카테고리: 경고.

설명

This issue appears when the tool detects the usage of pyspark.sql.dataframe.DataFrameStatFunctions.writeTo which has a workaround.

시나리오

입력

이 예제에서는 데이터프레임 df가 Spark 테이블 “table”에 기록됩니다.

writer = df.writeTo("table")

출력

SMA 는 DataFrameStatFunctions.writeTo가 사용되는 라인 위에 EWI SPRKPY1012 를 반환하므로 수정할 위치를 식별하는 데 사용할 수 있습니다.

#EWI: SPRKPY1012 => pyspark.sql.dataframe.DataFrameStatFunctions.writeTo has a workaround, see documentation for more info
writer = df.writeTo("table")

권장 수정

대신 df.write.SaveAsTable()를 사용합니다.

import df.write as wt
writer = df.write.save_as_table(table)

추가 권장 사항

SPRKPY1013

메시지: pyspark.sql.functions.acosh에 해결 방법이 있습니다

카테고리: 경고.

설명

This issue appears when the tool detects the usage of pyspark.sql.functions.acosh which has a workaround.

시나리오

입력

On this example pyspark calculates the acosh for a dataframe by using 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"]))

출력

SMA 는 acosh가 사용되는 라인 위에 EWI SPRKPY1013 를 반환하므로 수정할 위치를 식별하는 데 사용할 수 있습니다.

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

권장 수정

There is no direct “acosh” implementation but “call_function” can be used instead, using “acosh” as the first parameter, and colName as the second one.

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

추가 권장 사항

SPRKPY1014

메시지: pyspark.sql.functions.asinh에 해결 방법이 있습니다

카테고리: 경고.

설명

This issue appears when the tool detects the usage of pyspark.sql.functions.asinh which has a workaround.

시나리오

입력

On this example pyspark calculates the asinh for a dataframe by using 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"]))

출력

SMA 는 asinh이 사용되는 라인 위에 EWI SPRKPY1014 를 반환하므로 수정할 위치를 식별하는 데 사용할 수 있습니다.

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

권장 수정

There is no direct “asinh” implementation but “call_function” can be used instead, using “asinh” as the first parameter, and colName as the second one.

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

추가 권장 사항

SPRKPY1015

메시지: pyspark.sql.functions.atanh에 해결 방법이 있습니다

카테고리: 경고.

설명

This issue appears when the tool detects the usage of pyspark.sql.functions.atanh which has a workaround.

시나리오

입력

On this example pyspark calculates the atanh for a dataframe by using 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"]))

출력

SMA 는 atanh이 사용되는 라인 위에 EWI SPRKPY1015 를 반환하므로 수정할 위치를 식별하는 데 사용할 수 있습니다.

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

권장 수정

There is no direct “atanh” implementation but “call_function” can be used instead, using “atanh” as the first parameter, and colName as the second one.

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

추가 권장 사항

SPRKPY1016

경고

This issue code has been deprecated since Spark Conversion Core Version 0.11.7

메시지: pyspark.sql.functions.collect_set에 해결 방법이 있습니다

카테고리: 경고.

설명

This issue appears when the tool detects the usage of pyspark.sql.functions.collect_set which has a workaround.

시나리오

입력

Using collect*set to get the elements of _colname* without duplicates:

col = collect_set(colName)

출력

SMA 는 collect_set가 사용되는 라인에 EWI SPRKPY1016 을 반환하므로 수정할 위치를 식별하는 데 사용할 수 있습니다.

#EWI: SPRKPY1016 => pyspark.sql.functions.collect_set has a workaround, see documentation for more info
col = collect_set(colName)

권장 수정

Array_agg 함수를 사용하고 두 번째 인자에 true 값을 추가합니다.

col = array_agg(col, True)

추가 권장 사항

SPRKPY1017

경고

This issue code has been deprecated since Spark Conversion Core Version 4.8.0

pyspark.sql.functions.date_add에는 해결 방법이 있습니다

카테고리: 경고.

설명

This issue appears when the tool detects the usage of pyspark.sql.functions.date_add which has a workaround.

시나리오

입력

이 예제에서는 date_add를 사용하여 데이터프레임 df의 현재 날짜로부터 5일 후 날짜를 계산합니다.

col = df.select(date_add(df.colName, 5))

출력

SMA 는 date_add가 사용되는 라인 위에 EWI SPRKPY1017 를 반환하므로 수정할 위치를 식별하는 데 사용할 수 있습니다.

#EWI: SPRKPY1017 => pyspark.sql.functions.date_add has a workaround, see documentation for more info
col = df.select(date_add(df.colName, 5))

권장 수정

Import snowflake.snowpark.functions, which contains an implementation for date_add (and alias dateAdd) function.

from snowflake.snowpark.functions import date_add

col = df.select(date_add(df.dt, 1))

추가 권장 사항

SPRKPY1018

경고

This issue code has been deprecated since Spark Conversion Core Version 4.8.0

메시지: pyspark.sql.functions.date_sub에 해결 방법이 있습니다

카테고리: 경고.

설명

This issue appears when the tool detects the usage of pyspark.sql.functions.date_sub which has a workaround.

시나리오

입력

이 예제에서는 date_add를 사용하여 데이터프레임 df의 현재 날짜 5일 전 날짜를 계산합니다.

col = df.select(date_sub(df.colName, 5))

출력

SMA 는 date_sub가 사용되는 라인 위에 EWI SPRKPY1018 를 반환하므로 수정할 위치를 식별하는 데 사용할 수 있습니다.

#EWI: SPRKPY1018 => pyspark.sql.functions.date_sub has a workaround, see documentation for more info
col = df.select(date_sub(df.colName, 5))

권장 수정

Import snowflake.snowpark.functions, which contains an implementation for date_sub function.

from pyspark.sql.functions import date_sub
df.withColumn("date", date_sub(df.colName, 5))

추가 권장 사항

SPRKPY1019

경고

This issue code has been deprecated since Spark Conversion Core Version 4.8.0

메시지: pyspark.sql.functions.datediff에 해결 방법이 있습니다

카테고리: 경고.

설명

This issue appears when the tool detects the usage of pyspark.sql.functions.datediff which has a workaround.

시나리오

입력

이 예제에서는 datediff를 사용하여’오늘’과 다른 날짜의 요일 차이를 계산합니다.

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

출력

SMA 는 datediff가 사용되는 라인 위에 EWI SPRKPY1019 를 반환하므로 수정할 위치를 식별하는 데 사용할 수 있습니다.

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

SMA convert pyspark.sql.functions.datediff onto snowflake.snowpark.functions.daydiff that also calculates the diference in days between two dates.

권장 수정

datediff(부분: string, 종료: ColumnOrName, 시작: ColumnOrName)

Action: Import snowflake.snowpark.functions, which contains an implementation for datediff function that requires an extra parameter for date time part and allows more versatility on calculate differences between dates.

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

권장 사항

SPRKPY1020

메시지: pyspark.sql.functions.instr에 해결 방법이 있습니다

카테고리: 경고.

설명

This issue appears when the tool detects the usage of pyspark.sql.functions.instr which has a workaround.

시나리오

입력

다음은 pyspark 명령의 기본적인 사용 예시입니다.

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

출력:

SMA 는 instr이 사용되는 라인 위에 EWI SPRKPY1020 을 반환하므로 수정할 위치를 식별하는 데 사용할 수 있습니다.

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

권장 수정

Requires a manual change by using the function charindex and changing the order of the first two parameters.

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

추가 권장 사항

SPRKPY1021

경고

이 문제 코드는 사용 중단 되었습니다

메시지: pyspark.sql.functions.last에 해결 방법이 있습니다. 자세한 내용은 설명서를 참조하십시오

카테고리: 경고

설명

This issue appears when the SMA detects a use of the pyspark.sql.functions.last function, which has a workaround.

시나리오

입력

Below is an example of a use of the pyspark.sql.functions.last function that generates this EWI. In this example, the last function is used to get the last value for each name.

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

출력

The SMA adds the EWI SPRKPY1021 to the output code to let you know that this function is not directly supported by Snowpark, but it has a workaround.

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

권장 수정

As a workaround, you can use the Snowflake LAST_VALUE function. To invoke this function from Snowpark, use the snowflake.snowpark.functions.call_builtin function and pass the string last_value as the first argument and the corresponding column as the second argument. If you were using the name of the column in the last function, you should convert it into a column when calling the call_builtin function.

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

추가 권장 사항


description: >- The mode parameter in the methods of CSV, JSON and PARQUET is transformed to overwrite


SPRKPY1022

메시지: pyspark.sql.functions.log10에 해결 방법이 있습니다. 자세한 내용은 설명서를 참조하십시오

카테고리: 경고

설명

This issue appears when the SMA detects a use of the pyspark.sql.functions.log10 function, which has a workaround.

시나리오

입력

Below is an example of a use of the pyspark.sql.functions.log10 function that generates this EWI. In this example, the log10 function is used to calculate the base-10 logarithm of the value column.

df = spark.createDataFrame([(1,), (10,), (100,), (1000,), (10000,)], ["value"])
df_with_log10 = df.withColumn("log10_value", log10(df["value"]))

출력

The SMA adds the EWI SPRKPY1022 to the output code to let you know that this function is not directly supported by Snowpark, but it has a workaround.

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

권장 수정

As a workaround, you can use the snowflake.snowpark.functions.log function by passing the literal value 10 as the base.

df = spark.createDataFrame([(1,), (10,), (100,), (1000,), (10000,)], ["value"])
df_with_log10 = df.withColumn("log10_value", log(10, df["value"]))

추가 권장 사항

SPRKPY1023

메시지: pyspark.sql.functions.log1p에 해결 방법이 있습니다. 자세한 내용은 설명서를 참조하십시오

카테고리: 경고

설명

This issue appears when the SMA detects a use of the pyspark.sql.functions.log1p function, which has a workaround.

시나리오

입력

Below is an example of a use of the pyspark.sql.functions.log1p function that generates this EWI. In this example, the log1p function is used to calculate the natural logarithm of the value column.

df = spark.createDataFrame([(0,), (1,), (10,), (100,)], ["value"])
df_with_log1p = df.withColumn("log1p_value", log1p(df["value"]))

출력

The SMA adds the EWI SPRKPY1023 to the output code to let you know that this function is not directly supported by Snowpark, but it has a workaround.

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

권장 수정

As a workaround, you can use the call_function function by passing the string ln as the first argument and by adding 1 to the second argument.

df = spark.createDataFrame([(0,), (1,), (10,), (100,)], ["value"])
df_with_log1p = df.withColumn("log1p_value", call_function("ln", lit(1) + df["value"]))

추가 권장 사항

SPRKPY1024

메시지: pyspark.sql.functions.log2에 해결 방법이 있습니다. 자세한 내용은 설명서를 참조하십시오

카테고리: 경고

설명

This issue appears when the SMA detects a use of the pyspark.sql.functions.log2 function, which has a workaround.

시나리오

입력

Below is an example of a use of the pyspark.sql.functions.log2 function that generates this EWI. In this example, the log2 function is used to calculate the base-2 logarithm of the value column.

df = spark.createDataFrame([(1,), (2,), (4,), (8,), (16,)], ["value"])
df_with_log2 = df.withColumn("log2_value", log2(df["value"]))

출력

The SMA adds the EWI SPRKPY1024 to the output code to let you know that this function is not directly supported by Snowpark, but it has a workaround.

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

권장 수정

As a workaround, you can use the snowflake.snowpark.functions.log function by passing the literal value 2 as the base.

df = session.createDataFrame([(1,), (2,), (4,), (8,), (16,)], ["value"])
df_with_log2 = df.withColumn("log2_value", log(2, df["value"]))

추가 권장 사항

SPRKPY1025

경고

이 문제 코드는 사용 중단 되었습니다

메시지: pyspark.sql.functions.ntile에 해결 방법이 있습니다. 자세한 내용은 설명서를 참조하십시오

카테고리: 경고

설명

This issue appears when the SMA detects a use of the pyspark.sql.functions.ntile function, which has a workaround.

시나리오

입력

Below is an example of a use of the pyspark.sql.functions.ntile function that generates this EWI. In this example, the ntile function is used to divide the rows into 3 buckets.

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

출력

The SMA adds the EWI SPRKPY1025 to the output code to let you know that this function is not directly supported by Snowpark, but it has a workaround.

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

권장 수정

Snowpark has an equivalent ntile function, however, the argument pass to it should be a column. As a workaround, you can convert the literal argument into a column using the snowflake.snowpark.functions.lit function.

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

추가 권장 사항

SPRKPY1026

경고

This issue code has been deprecated since Spark Conversion Core 4.3.2

메시지: pyspark.sql.readwriter.DataFrameReader.csv에 해결 방법이 있습니다. 자세한 내용은 설명서를 참조하십시오

카테고리: 경고

설명

This issue appears when the SMA detects a use of the pyspark.sql.readwriter.DataFrameReader.csv function, which has a workaround.

시나리오

입력

Below is an example of a use of the pyspark.sql.readwriter.DataFrameReader.csv function that generates this EWI. In this example, the csv function is used to read multiple .csv files with a given schema and uses some extra options such as encoding, header and sep to fine-tune the behavior of reading the files.

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

출력

The SMA adds the EWI SPRKPY1026 to the output code to let you know that this function is not directly supported by Snowpark, but it has a workaround.

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

권장 수정

In this section, we explain how to configure the path parameter, the schema parameter and some options to make them work in Snowpark.

1. path 매개 변수

Snowpark requires the path parameter to be a stage location so, as a workaround, you can create a temporary stage and add each .csv file to that stage using the prefix file://.

2. schema 매개 변수

Snowpark does not allow defining the schema as a parameter of the csv function. As a workaround, you can use the snowflake.snowpark.DataFrameReader.schema function.

3. options 매개 변수

Snowpark does not allow defining the extra options as parameters of the csv function. As a workaround, for many of them you can use the snowflake.snowpark.DataFrameReader.option function to specify those parameters as options of the DataFrameReader.

참고

다음 옵션은 Snowpark에서 지원되지 않음:

  • columnNameOfCorruptRecord

  • emptyValue

  • enforceSchema

  • 헤더

  • ignoreLeadingWhiteSpace

  • ignoreTrailingWhiteSpace

  • 추론 스키마

  • locale

  • maxCharsPerColumn

  • maxColumns

  • 모드

  • multiLine

  • nanValue

  • negativeInf

  • nullValue

  • positiveInf

  • quoteAll

  • samplingRatio

  • timestampNTZFormat

  • unescapedQuoteHandling

아래는 위에서 언급한 제안을 적용하여 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)

추가 권장 사항

SPRKPY1027

경고

This issue code has been deprecated since Spark Conversion Core 4.5.2

메시지: DataFrameReader.json에 해결 방법이 있습니다. 자세한 내용은 설명서를 참조하십시오

카테고리: 경고

설명

This issue appears when the SMA detects a use of the pyspark.sql.readwriter.DataFrameReader.json function, which has a workaround.

시나리오

입력

Below is an example of a use of the pyspark.sql.readwriter.DataFrameReader.json function that generates this EWI. In this example, the json function is used to read multiple .json files with a given schema and uses some extra options such as primitiveAsString and dateFormat to fine-tune the behavior of reading the files.

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

출력

The SMA adds the EWI SPRKPY1027 to the output code to let you know that this function is not directly supported by Snowpark, but it has a workaround.

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

권장 수정

In this section, we explain how to configure the path parameter, the schema parameter and some options to make them work in Snowpark.

1. path 매개 변수

Snowpark requires the path parameter to be a stage location so, as a workaround, you can create a temporary stage and add each .json file to that stage using the prefix file://.

2. schema 매개 변수

Snowpark does not allow defining the schema as a parameter of the json function. As a workaround, you can use the snowflake.snowpark.DataFrameReader.schema function.

3. options 매개 변수

Snowpark does not allow defining the extra options as parameters of the json function. As a workaround, for many of them you can use the snowflake.snowpark.DataFrameReader.option function to specify those parameters as options of the DataFrameReader.

참고

다음 옵션은 Snowpark에서 지원되지 않음:

  • allowBackslashEscapingAnyCharacter

  • allowComments

  • allowNonNumericNumbers

  • allowNumericLeadingZero

  • allowSingleQuotes

  • allowUnquotedControlChars

  • allowUnquotedFieldNames

  • columnNameOfCorruptRecord

  • dropFiledIfAllNull

  • 인코딩

  • ignoreNullFields

  • lineSep

  • locale

  • 모드

  • multiline

  • prefersDecimal

  • primitiveAsString

  • samplingRatio

  • timestampNTZFormat

  • timeZone

아래는 위에서 언급한 제안을 적용하여 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)

추가 권장 사항

SPRKPY1028

메시지: pyspark.sql.readwriter.DataFrameReader.orc에 해결 방법이 있습니다. 자세한 내용은 설명서를 참조하십시오

카테고리: 경고

설명

This issue appears when the SMA detects a use of the pyspark.sql.readwriter.DataFrameReader.orc function, which has a workaround.

시나리오

입력

Below is an example of a use of the pyspark.sql.readwriter.DataFrameReader.orc function that generates this EWI. In this example, the orc function is used to read multiple .orc files and uses some extra options such as mergeSchema and recursiveFileLookup to fine-tune the behavior of reading the files.

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

출력

The SMA adds the EWI SPRKPY1028 to the output code to let you know that this function is not directly supported by Snowpark, but it has a workaround.

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

권장 수정

In this section, we explain how to configure the path parameter and the extra options to make them work in Snowpark.

1. path 매개 변수

Snowpark requires the path parameter to be a stage location so, as a workaround, you can create a temporary stage and add each .orc file to that stage using the prefix file://.

2. options 매개 변수

Snowpark does not allow defining the extra options as parameters of the orc function. As a workaround, for many of them you can use the snowflake.snowpark.DataFrameReader.option function to specify those parameters as options of the DataFrameReader.

참고

다음 옵션은 Snowpark에서 지원되지 않음:

  • 압축

  • mergeSchema

아래는 위에서 언급한 제안을 적용하여 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)

추가 권장 사항

SPRKPY1029

메시지: 이 문제는 도구가 pyspark.sql.readwriter.DataFrameReader.parquet의 사용을 감지할 때 표시됩니다. 이 함수는 지원되지만, Snowpark와 Spark API 간의 일부 차이점 때문에 일부 수동 변경이 필요할 수 있습니다.

카테고리: 경고

설명

This issue appears when the SMA detects a use of the pyspark.sql.readwriter.DataFrameReader.parquet function. This function is supported by Snowpark, however, there are some differences that would require some manual changes.

시나리오

입력

Below is an example of a use of the pyspark.sql.readwriter.DataFrameReader.parquet function that generates this 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"
)

출력

The SMA adds the EWI SPRKPY1029 to the output code to let you know that this function is supported by Snowpark, but it requires some manual adjustments. Please note that the options supported by Snowpark are transformed into option function calls and those that are not supported are removed. This is explained in more detail in the next sections.

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
)

권장 수정

In this section, we explain how to configure the paths and options parameters to make them work in Snowpark.

1. paths 매개 변수

In Spark, this parameter can be a local or cloud location. Snowpark only accepts cloud locations using a snowflake stage. So, you can create a temporal stage and add each file into it using the prefix file://.

2. options 매개 변수

Snowpark does not allow defining the different options as parameters of the parquet function. As a workaround, you can use the option or options functions to specify those parameters as extra options of the DataFrameReader.

Snowpark options 은 PySpark options 와 정확하게 동일하지 않으므로 일부 수동 변경이 필요할 수 있습니다. 다음은 Snowpark에서 가장 일반적인 PySpark 옵션을 구성하는 방법에 대한 자세한 설명입니다.

2.1 mergeSchema 옵션

Parquet supports schema evolution, allowing users to start with a simple schema and gradually add more columns as needed. This can result in multiple parquet files with different but compatible schemas. In Snowflake, thanks to the infer_schema capabilities you don’t need to do that and therefore the mergeSchema option can just be removed.

2.2 pathGlobFilter 옵션

If you want to load only a subset of files from the stage, you can use the pattern option to specify a regular expression that matches the files you want to load. The SMA already automates this as you can see in the output of this scenario.

2.3 recursiveFileLookupstr 옵션

This option is not supported by Snowpark. The best recommendation is to use a regular expression like with the pathGlobFilter option to achieve something similar.

2.4 modifiedBefore / modifiedAfter 옵션

You can achieve the same result in Snowflake by using the metadata columns.

참고

다음 옵션은 Snowpark에서 지원되지 않음:

  • 압축

  • datetimeRebaseMode

  • int96RebaseMode

  • mergeSchema

아래는 입력 코드가 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')

추가 권장 사항

SPRKPY1030

경고

이 문제 코드는 사용 중단 되었습니다

메시지: pyspark.sql.세션. SparkSession .Builder.appName에 해결 방법이 있습니다. 자세한 내용은 설명서를 참조하십시오

카테고리: 경고

설명

This issue appears when the SMA detects a use of the pyspark.sql.session.SparkSession.Builder.appName function, which has a workaround.

시나리오

입력

Below is an example of a use of the pyspark.sql.session.SparkSession.Builder.appName function that generates this EWI. In this example, the appName function is used to set MyApp as the name of the application.

session = SparkSession.builder.appName("MyApp").getOrCreate()

출력

The SMA adds the EWI SPRKPY1030 to the output code to let you know that this function is not directly supported by Snowpark, but it has a workaround.

#EWI: SPRKPY1030 => pyspark.sql.session.SparkSession.Builder.appName has a workaround, see documentation for more info
session = Session.builder.appName("MyApp").getOrCreate()

권장 수정

As a workaround, you can import the snowpark_extensions package which provides an extension for the appName function.

import snowpark_extensions
session = SessionBuilder.appName("MyApp").getOrCreate()

추가 권장 사항

SPRKPY1031

경고

This issue code has been deprecated since Spark Conversion Core 2.7.0

메시지: pyspark.sql.column.Column.contains에 해결 방법이 있습니다. 자세한 내용은 설명서를 참조하십시오

카테고리: 경고

설명

This issue appears when the SMA detects a use of the pyspark.sql.column.Column.contains function, which has a workaround.

시나리오

입력

Below is an example of a use of the pyspark.sql.column.Column.contains function that generates this EWI. In this example, the contains function is used to filter the rows where the ‘City’ column contains the substring ‘New’.

df = spark.createDataFrame([("Alice", "New York"), ("Bob", "Los Angeles"), ("Charlie", "Chicago")], ["Name", "City"])
df_filtered = df.filter(col("City").contains("New"))

출력

The SMA adds the EWI SPRKPY1031 to the output code to let you know that this function is not directly supported by Snowpark, but it has a workaround.

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

권장 수정

As a workaround, you can use the snowflake.snowpark.functions.contains function by passing the column as the first argument and the element to search as the second argument. If the element to search is a literal value then it should be converted into a column expression using the lit function.

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

추가 권장 사항

SPRKPY1032

Message: *spark element* is not defined

카테고리: 변환 오류

설명

이 문제는 SMA 에서 지정된 요소에 대한 적절한 매핑 상태를 확인할 수 없을 때 표시됩니다. 즉, SMA 는 이 요소가 Snowpark에서 지원되는지 여부를 아직 알지 못합니다. 이 코드는 정의되지 않은 요소에 대해 SMA 가 사용하는 일반적인 오류 코드입니다.

시나리오

입력

Below is an example of a function for which the SMA could not determine an appropriate mapping status. In this case, you should assume that not_defined_function() is a valid PySpark function and the code runs.

sc.parallelize(["a", "b", "c", "d", "e"], 3).not_defined_function().collect()

출력

The SMA adds the EWI SPRKPY1032 to the output code to let you know that this element is not defined.

#EWI: SPRKPY1032 => pyspark.rdd.RDD.not_defined_function is not defined
sc.parallelize(["a", "b", "c", "d", "e"], 3).not_defined_function().collect()

권장 수정

문제를 식별하기 위해 다음 유효성 검사를 수행할 수 있습니다.

  • 소스 코드의 구문이 올바른지, 철자가 올바른지 확인하십시오.

  • Check if you are using a PySpark version supported by the SMA. To know which PySpark version is supported by the SMA at the moment of running the SMA, you can review the first page of the DetailedReport.docx file.

If this is a valid PySpark element, please report that you encountered a conversion error on that particular element using the Report an Issue option of the SMA and include any additional information that you think may be helpful.

Please note that if an element is not defined, it does not mean that it is not supported by Snowpark. You should check the Snowpark Documentation to verify if an equivalent element exist.

추가 권장 사항

SPRKPY1033

경고

이 문제 코드는 사용 중단 되었습니다

메시지: pyspark.sql.functions.asc에 해결 방법이 있습니다. 자세한 내용은 설명서를 참조하십시오

카테고리: 경고

설명

This issue appears when the SMA detects a use of the pyspark.sql.functions.asc function, which has a workaround.

시나리오

The pyspark.sql.functions.asc function takes either a column object or the name of the column as a string as its parameter. Both scenarios are not supported by Snowpark so this EWI is generated.

시나리오 1

입력

Below is an example of a use of the pyspark.sql.functions.asc function that takes a column object as parameter.

df.orderBy(asc(col))

출력

The SMA adds the EWI SPRKPY1033 to the output code to let you know that the asc function with a column object parameter is not directly supported by Snowpark, but it has a workaround.

#EWI: SPRKPY1033 => pyspark.sql.functions.asc has a workaround, see documentation for more info
df.orderBy(asc(col))

권장 수정

As a workaround, you can call the snowflake.snowpark.Column.asc function from the column parameter.

df.orderBy(col.asc())
시나리오 2

입력

Below is an example of a use of the pyspark.sql.functions.asc function that takes the name of the column as parameter.

df.orderBy(asc("colName"))

출력

The SMA adds the EWI SPRKPY1033 to the output code to let you know that the asc function with a column name parameter is not directly supported by Snowpark, but it has a workaround.

#EWI: SPRKPY1033 => pyspark.sql.functions.asc has a workaround, see documentation for more info
df.orderBy(asc("colName"))

권장 수정

As a workaround, you can convert the string parameter into a column object using the snowflake.snowpark.functions.col function and then call the snowflake.snowpark.Column.asc function.

df.orderBy(col("colName").asc())

추가 권장 사항

SPRKPY1034

경고

이 문제 코드는 사용 중단 되었습니다

메시지: pyspark.sql.functions.desc에 해결 방법이 있습니다. 자세한 내용은 설명서를 참조하십시오

카테고리: 경고

설명

This issue appears when the SMA detects a use of the pyspark.sql.functions.desc function, which has a workaround.

시나리오

The pyspark.sql.functions.desc function takes either a column object or the name of the column as a string as its parameter. Both scenarios are not supported by Snowpark so this EWI is generated.

시나리오 1

입력

Below is an example of a use of the pyspark.sql.functions.desc function that takes a column object as parameter.

df.orderBy(desc(col))

출력

The SMA adds the EWI SPRKPY1034 to the output code to let you know that the desc function with a column object parameter is not directly supported by Snowpark, but it has a workaround.

#EWI: SPRKPY1034 => pyspark.sql.functions.desc has a workaround, see documentation for more info
df.orderBy(desc(col))

권장 수정

As a workaround, you can call the snowflake.snowpark.Column.desc function from the column parameter.

df.orderBy(col.desc())
시나리오 2

입력

Below is an example of a use of the pyspark.sql.functions.desc function that takes the name of the column as parameter.

df.orderBy(desc("colName"))

출력

The SMA adds the EWI SPRKPY1034 to the output code to let you know that the desc function with a column name parameter is not directly supported by Snowpark, but it has a workaround.

#EWI: SPRKPY1034 => pyspark.sql.functions.desc has a workaround, see documentation for more info
df.orderBy(desc("colName"))

권장 수정

As a workaround, you can convert the string parameter into a column object using the snowflake.snowpark.functions.col function and then call the snowflake.snowpark.Column.desc function.

df.orderBy(col("colName").desc())

추가 권장 사항

SPRKPY1035

경고

이 문제 코드는 사용 중단 되었습니다

메시지: pyspark.sql.functions.reverse에 해결 방법이 있습니다. 자세한 내용은 설명서를 참조하십시오

카테고리: 경고

설명

This issue appears when the SMA detects a use of the pyspark.sql.functions.reverse function, which has a workaround.

시나리오

입력

Below is an example of a use of the pyspark.sql.functions.reverse function that generates this EWI. In this example, the reverse function is used to reverse each string of the word column.

df = spark.createDataFrame([("hello",), ("world",)], ["word"])
df_reversed = df.withColumn("reversed_word", reverse(df["word"]))
df_reversed = df.withColumn("reversed_word", reverse("word"))

출력

The SMA adds the EWI SPRKPY1035 to the output code to let you know that this function is not directly supported by Snowpark, but it has a workaround.

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

권장 수정

As a workaround, you can import the snowpark_extensions package which provides an extension for the reverse function.

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

추가 권장 사항

SPRKPY1036

경고

이 문제 코드는 사용 중단 되었습니다

메시지: pyspark.sql.column.Column.getField에 해결 방법이 있습니다. 자세한 내용은 설명서를 참조하십시오

카테고리: 경고

설명

This issue appears when the SMA detects a use of the pyspark.sql.column.Column.getField function, which has a workaround.

시나리오

입력

Below is an example of a use of the pyspark.sql.column.Column.getField function that generates this EWI. In this example, the getField function is used to extract the name from the info column.

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

출력

The SMA adds the EWI SPRKPY1036 to the output code to let you know that this function is not directly supported by Snowpark, but it has a workaround.

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

권장 수정

As a workaround, you can use the Snowpark column indexer operator with the name of the field as the index.

df = spark.createDataFrame([(1, {"name": "John", "age": 30}), (2, {"name": "Jane", "age": 25})], ["id", "info"])
df_with_name = df.withColumn("name", col("info")["name"])

추가 권장 사항

SPRKPY1037

경고

이 문제 코드는 사용 중단 되었습니다

메시지: pyspark.sql.functions.sort_array에 해결 방법이 있습니다. 자세한 내용은 설명서를 참조하십시오

카테고리: 경고

설명

This issue appears when the SMA detects a use of the pyspark.sql.functions.sort_array function, which has a workaround.

시나리오

입력

Below is an example of a use of the pyspark.sql.functions.sort_array function that generates this EWI. In this example, the sort_array function is used to sort the numbers array in ascending and descending order.

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

출력

The SMA adds the EWI SPRKPY1037 to the output code to let you know that this function is not directly supported by Snowpark, but it has a workaround.

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

권장 수정

As a workaround, you can import the snowpark_extensions package which provides an extension for the sort_array function.

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

추가 권장 사항

SPRKPY1038

Message: *spark element* is not yet recognized

카테고리: 변환 오류

설명

이 문제는 소스 코드에 SMA 가 인식하지 못한 PySpark 요소가 있을 때 표시됩니다. 이는 다음과 같은 다양한 이유로 발생할 수 있습니다.

  • PySpark 에 존재하지 않는 요소입니다.

  • SMA 버전에서 아직 지원하지 않는 PySpark 버전에 추가된 요소입니다.

  • 요소를 처리할 때 SMA 의 내부 오류입니다.

인식되지 않는 요소에 대해 SMA 에서 사용하는 일반적인 오류 코드입니다.

시나리오

입력

아래는 PySpark 에 존재하지 않아 SMA 에서 인식할 수 없는 함수를 사용한 예제입니다.

from pyspark.sql import functions as F
F.unrecognized_function()

출력

The SMA adds the EWI SPRKPY1038 to the output code to let you know that this element could not be recognized.

from snowflake.snowpark import functions as F
#EWI: SPRKPY1038 => pyspark.sql.functions.non_existent_function is not yet recognized
F.unrecognized_function()

권장 수정

문제를 식별하기 위해 다음 유효성 검사를 수행할 수 있습니다.

  • PySpark 에 요소가 있는지 확인합니다.

  • 요소의 철자가 올바른지 확인합니다.

  • Check if you are using a PySpark version supported by the SMA. To know which PySpark version is supported by the SMA at the moment of running the SMA, you can review the first page of the DetailedReport.docx file.

If it is a valid PySpark element, please report that you encountered a conversion error on that particular element using the Report an Issue option of the SMA and include any additional information that you think may be helpful.

Please note that if an element could not be recognized by the SMA, it does not mean that it is not supported by Snowpark. You should check the Snowpark Documentation to verify if an equivalent element exist.

추가 권장 사항

SPRKPY1039

경고

이 문제 코드는 사용 중단 되었습니다

메시지: pyspark.sql.column.Column.getItem에 해결 방법이 있습니다. 자세한 내용은 설명서를 참조하십시오

카테고리: 경고

설명

This issue appears when the SMA detects a use of the pyspark.sql.column.Column.getItem function, which has a workaround.

시나리오

입력

Below is an example of a use of the pyspark.sql.column.Column.getItem function that generates this EWI. In this example, the getItem function is used to get an item by position and by key.

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

출력

The SMA adds the EWI SPRKPY1039 to the output code to let you know that this function is not directly supported by Snowpark, but it has a workaround.

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

권장 수정

해결 방법으로 필드의 이름 또는 위치를 인덱스로 사용하여 Snowpark 열 인덱서 연산자 를 사용할 수 있습니다.

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

추가 권장 사항

SPRKPY1040

경고

이 문제 코드는 사용 중단 되었습니다

메시지: pyspark.sql.functions.explode로 해결할 수 있습니다. 자세한 내용은 설명서를 참조하십시오.

카테고리: 경고

설명

This issue appears when the SMA detects a use of the pyspark.sql.functions.explode function, which has a workaround.

시나리오

입력

Below is an example of a use of the pyspark.sql.functions.explode function that generates this EWI. In this example, the explode function is used to generate one row per array item for the numbers column.

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

출력

The SMA adds the EWI SPRKPY1040 to the output code to let you know that this function is not directly supported by Snowpark, but it has a workaround.

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

권장 수정

As a workaround, you can import the snowpark_extensions package which provides an extension for the explode function.

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

추가 권장 사항

SPRKPY1041

경고

This issue code has been deprecated since Spark Conversion Core Version 2.9.0

메시지: pyspark.sql.functions.explode_outer에 해결 방법이 있습니다

카테고리: 경고

설명

This issue appears when the tool detects the usage of pyspark.sql.functions.explode_outer which has a workaround.

시나리오

입력

이 예제는 select 호출에서 explode_outer 메서드를 사용하는 방법을 보여줍니다.

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

출력

The tool adds the EWI SPRKPY1041 indicating that a workaround can be implemented.

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

권장 수정

As a workaround, you can import the snowpark_extensions package, which contains a helper for the explode_outer function.

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

추가 권장 사항

SPRKPY1042

메시지: pyspark.sql.functions.posexplode에 해결 방법이 있습니다

카테고리: 경고

설명

This issue appears when the tool detects the usage of pyspark.sql.functions.posexplode which has a workaround.

시나리오

There are a couple of scenarios that this method can handle depending on the type of column it is passed as a parameter, it can be a list of values or a map/directory (keys/values).

시나리오 1

입력

Below is an example of the usage of posexplode passing as a parameter of a list of values.

df = spark.createDataFrame(
    [Row(a=1,
         intlist=[1, 2, 3])])

df.select(posexplode(df.intlist)).collect()

출력

The tool adds the EWI SPRKPY1042 indicating that a workaround can be implemented.

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

권장 수정

For having the same behavior, use the method functions.flatten, drop extra columns, and rename index and value column names.

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()
시나리오 2

입력

Below is another example of the usage of posexplode passing as a parameter a map/dictionary (keys/values)

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

출력

The tool adds the EWI SPRKPY1042 indicating that a workaround can be implemented.

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

권장 수정

As a workaround, you can use functions.row_number to get the position and functions.explode with the name of the field to get the value the key/value for dictionaries.

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

참고: row_number를 사용하는 것은 1로 시작하기 때문에 완전히 동일하지 않습니다(Spark 메서드처럼 0이 아님)

추가 권장 사항

SPRKPY1043

메시지: pyspark.sql.functions.posexplode_outer에 해결 방법이 있습니다

카테고리: 경고

설명

This issue appears when the tool detects the usage of pyspark.sql.functions.posexplode_outer which has a workaround.

시나리오

There are a couple of scenarios that this method can handle depending on the type of column it is passed as a parameter, it can be a list of values or a map/directory (keys/values).

시나리오 1

입력

Below is an example that shows the usage of posexplode_outer passing a list of values.

df = spark.createDataFrame(
    [
        (1, ["foo", "bar"]),
        (2, []),
        (3, None)],
    ("id", "an_array"))

df.select("id", "an_array", posexplode_outer("an_array")).show()

출력

The tool adds the EWI SPRKPY1043 indicating that a workaround can be implemented.

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

권장 수정

For having the same behavior, use the method functions.flatten sending the outer parameter in True, drop extra columns, and rename index and value column names.

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()
시나리오 2

입력

map/dictionary (keys/values) 을 전달하는 posexplode_outer의 또 다른 사용 예는 다음과 같습니다.

df = spark.createDataFrame(
    [
        (1, {"x": 1.0}),
        (2, {}),
        (3, None)],
    ("id", "a_map"))

df.select(posexplode_outer(df.a_map)).show()

출력

The tool adds the EWI SPRKPY1043 indicating that a workaround can be implemented.

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

권장 수정

As a workaround, you can use functions.row_number to get the position and functions.explode_outer with the name of the field to get the value of the key/value for dictionaries.

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

참고: row_number를 사용하는 것은 1로 시작하기 때문에 완전히 동일하지 않습니다(Spark 메서드처럼 0이 아님)

추가 권장 사항

SPRKPY1044

경고

This issue code has been deprecated since Spark Conversion Core Version 2.4.0

메시지: pyspark.sql.functions.split에 해결 방법이 있습니다

카테고리: 경고.

설명

This issue appears when the tool detects the usage of pyspark.sql.functions.split which has a workaround.

시나리오

메서드에 전달되는 매개 변수의 양에 따라 몇 가지 시나리오가 있습니다.

시나리오 1

입력

Below is an example when the function split has just the str and pattern parameters

F.split('col', '\\|')

출력

The tool shows the EWI SPRKPY1044 indicating there is a workaround.

#EWI: SPRKPY1044 => pyspark.sql.functions.split has a workaround, see the documentation for more info
F.split('col', '\\|')

권장 수정

As a workaround, you can call the function snowflake.snowpark.functions.lit with the pattern parameter and send it into the split.

F.split('col', lit('\\|'))
## the result of lit will be sent to the split function

시나리오 2

입력

Below is another example when the function split has the str, pattern, and limit parameters.

F.split('col', '\\|', 2)

출력

The tool shows the EWI SPRKPY1044 indicating there is a workaround.

#EWI: SPRKPY1044 => pyspark.sql.functions.split has a workaround, see the documentation for more info
F.split('col', '\\|', 2)

권장 수정

이 특정 시나리오는 지원되지 않습니다.

추가 권장 사항

SPRKPY1045

메시지: pyspark.sql.functions.map_values에 해결 방법이 있습니다

카테고리: 경고.

설명

이 함수는 map/dictionary (keys/values) 이 포함된 열에서 값 목록을 추출하는 데 사용됩니다.

The issue appears when the tool detects the usage of pyspark.sql.functions.map_values which has a workaround.

시나리오

입력

Below is an example of the usage of the method map_values.

df = spark.createDataFrame(
    [(1, {'Apple': 'Fruit', 'Potato': 'Vegetable'})],
    ("id", "a_map"))

df.select(map_values("a_map")).show()

출력

The tool adds the EWI SPRKPY1045 indicating that a workaround can be implemented.

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

권장 수정

As a workaround, you can create an udf to get the values for a column. The below example shows how to create the udf, then assign it to F.map_values, and then make use of it.

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

추가 권장 사항

SPRKPY1046

경고

This issue code has been deprecated since Spark Conversion Core Version 2.1.22

메시지: pyspark.sql.functions.monotonically_increasing_id에 해결 방법이 있습니다

카테고리: 경고.

설명

This issue appears when the tool detects the usage of pyspark.sql.functions.monotonically_increasing_id which has a workaround.

시나리오

입력

Below is an example of the usage of the method monotonically_increasing_id.

from pyspark.sql import functions as F

spark.range(0, 10, 1, 2).select(F.monotonically_increasing_id()).show()

출력

The tool adds the EWI SPRKPY1046 indicating that a workaround can be implemented.

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

권장 수정

도구 버전을 업데이트합니다.

추가 권장 사항

SPRKPY1047

경고

This issue code has been deprecated since Spark Conversion Core Version 4.6.0

설명

This issue appears when the tool detects the usage of pyspark.context.SparkContext.setLogLevel which has a workaround.

시나리오

입력

Below is an example of the usage of the method setLogLevel.

sparkSession.sparkContext.setLogLevel("WARN")

출력

The tool adds the EWI SPRKPY1047 indicating that a workaround can be implemented.

#EWI: SPRKPY1047 => pyspark.context.SparkContext.setLogLevel has a workaround, see documentation for more info
sparkSession.sparkContext.setLogLevel("WARN")

권장 수정

Replace the setLogLevel function usage with logging.basicConfig that provides a set of convenience functions for simple logging usage. In order to use it, we need to import two modules, “logging” and “sys”, and the level constant should be replaced using the “Level equivalent table”:

import logging
import sys
logging.basicConfig(stream=sys.stdout, level=logging.WARNING)
  • 레벨 등가 테이블

레벨 소스 매개 변수

레벨 대상 매개 변수

“ALL”

<mark style=”color:red;”>**This has no equivalent**</mark>

“DEBUG”

logging.DEBUG

“ERROR”

logging.ERROR

“FATAL”

logging.CRITICAL

“INFO”

logging.INFO

“OFF”

logging.NOTSET

“TRACE”

<mark style=”color:red;”>**This has no equivalent**</mark>

“WARN”

logging.WARNING

추가 권장 사항

SPRKPY1048

경고

This issue code has been deprecated since Spark Conversion Core Version 2.4.0

메시지: pyspark.sql.session.SparkSession.conf에 해결 방법이 있습니다

카테고리: 경고.

설명

This issue appears when the tool detects the usage of pyspark.sql.session.SparkSession.conf which has a workaround.

시나리오

입력

Below is an example of how to set a configuration into the property conf .

spark.conf.set("spark.sql.crossJoin.enabled", "true")

출력

The tool adds the EWI SPRKPY1048 indicating that a workaround can be implemented.

#EWI: SPRKPY1048 => pyspark.sql.session.SparkSession.conf has a workaround, see documentation for more info
spark.conf.set("spark.sql.crossJoin.enabled", "true")

권장 수정

SparkSession.conf는 Pyspark에서만 사용하는 일부 특정 설정을 전달하는 데 사용되며 Snowpark에는 적용되지 않습니다. 코드를 제거하거나 설명할 수 있습니다

#spark.conf.set("spark.sql.crossJoin.enabled", "true")

추가 권장 사항

SPRKPY1049

경고

This issue code has been deprecated since Spark Conversion Core Version 2.1.9

메시지: pyspark.sql.session.SparkSession.sparkContext에 해결 방법이 있습니다

카테고리: 경고.

설명

This issue appears when the tool detects the usage of pyspark.sql.session.SparkSession.sparkContext which has a workaround.

시나리오

입력

Below is an example that creates a spark session and then uses the SparkContext property to print the appName.

print("APP Name :"+spark.sparkContext.appName())

출력

The tool adds the EWI SPRKPY1049 indicating that a workaround can be implemented.

#EWI: SPRKPY1049 => pyspark.sql.session.SparkSession.sparkContext has a workaround, see documentation for more info
print("APP Name :"+spark.sparkContext.appName())

권장 수정

SparkContext 는 SnowPark 에서 지원되지 않지만, SparkContext 의 세션 인스턴스에서 직접 메서드와 속성에 액세스할 수 있습니다.

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

추가 권장 사항

SPRKPY1050

메시지: pyspark.conf.SparkConf.set에 해결 방법이 있습니다

카테고리: 경고.

설명

This issue appears when the tool detects the usage of pyspark.conf.SparkConf.set which has a workaround.

시나리오

입력

Below is an example that sets a variable using conf.set.

conf = SparkConf().setAppName('my_app')

conf.set("spark.storage.memoryFraction", "0.5")

출력

The tool adds the EWI SPRKPY1050 indicating that a workaround can be implemented.

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

권장 수정

SparkConf.set은 Pyspark에서만 사용하는 구성 설정을 설정하는 데 사용되며 Snowpark에는 적용되지 않습니다. 코드를 제거하거나 설명할 수 있습니다

#conf.set("spark.storage.memoryFraction", "0.5")

추가 권장 사항

SPRKPY1051

경고

This issue code has been deprecated since Spark Conversion Core Version 2.4.0

메시지: pyspark.sql.세션.SparkSession.Builder.master에 해결 방법이 있습니다

카테고리: 경고.

설명

This issue appears when the tool detects pyspark.sql.session.SparkSession.Builder.master usage which has a workaround.

시나리오

입력

Below is an example of the usage of the method builder.master to set the Spark Master URL to connect to local using 1 core.

spark = SparkSession.builder.master("local[1]")

출력

The tool adds the EWI SPRKPY1051 indicating that a workaround can be implemented.

#EWI: SPRKPY1051 => pyspark.sql.session.SparkSession.Builder.master has a workaround, see documentation for more info
spark = Session.builder.master("local[1]")

권장 수정

pyspark.sql.session.SparkSession.Builder.master is used to set up a Spark Cluster. Snowpark doesn’t use Spark Clusters so you can remove or comment the code.

## spark = Session.builder.master("local[1]")

추가 권장 사항

SPRKPY1052

경고

This issue code has been deprecated since Spark Conversion Core Version 2.8.0

메시지: pyspark.sql.session.SparkSession.Builder.enableHiveSupport 에 해결 방법이 있습니다

카테고리: 경고.

설명

This issue appears when the tool detects the usage of pyspark.sql.session.SparkSession.Builder.enableHiveSupport which has a workaround.

시나리오

입력

Below is an example that configures the SparkSession and enables the hive support using the method enableHiveSupport.

spark = Session.builder.appName("Merge_target_table")\
        .config("spark.port.maxRetries","100") \
        .enableHiveSupport().getOrCreate()

출력

The tool adds the EWI SPRKPY1052 indicating that a workaround can be implemented.

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

권장 수정

Remove the use of enableHiveSupport function because it is not needed in Snowpark.

spark = Session.builder.appName("Merge_target_table")\
        .config("spark.port.maxRetries","100") \
        .getOrCreate()

추가 권장 사항

SPRKPY1053

메시지: Dbc 파일을 추출하는 동안 오류가 발생했습니다.

카테고리: 경고.

설명

이 문제는 dbc 파일을 추출할 수 없을 때 표시됩니다. 이 경고는 다음 중 한 가지 이상의 이유로 인해 발생할 수 있습니다. 너무 무겁거나, 액세스할 수 없거나, 읽기 전용입니다.

추가 권장 사항

  • 해결 방법으로 파일이 너무 커서 처리할 수 없는 경우 파일 크기를 확인할 수 있습니다. 또한 도구가 액세스할 수 있는지 분석하여 액세스 문제를 방지하십시오.

  • 자세한 지원이 필요하면 이메일(snowconvert-info@Snowflake.com)로 문의하십시오. Snowflake와 지원 계약을 맺은 경우 영업 엔지니어에게 문의하면 지원 요구 사항을 안내해 드릴 수 있습니다.

SPRKPY1080

메시지: SparkContext 값은 ‘session’ 변수로 대체되었습니다.

카테고리: 경고

설명

Spark 컨텍스트는 Snowpark 세션을 생성하는 세션이라는 변수에 저장됩니다.

시나리오

입력

이 스니펫은 SparkContext 를 설명합니다.

## Input Code
from pyspark import SparkContext
from pyspark.sql import SparkSession

def example1():

    sc = SparkContext("local[*]", "TestApp")

    sc.setLogLevel("ALL")
    sc.setLogLevel("DEBUG")

출력

이 출력 코드에서 SMA 는 PySpark.SparkContext 를 SparkSession 로 바꿨습니다. SMA 도 “connection.json” 파일에 연결을 대체하는 템플릿을 추가한 다음 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)

권장 수정

구성 파일 “connection.json”을 필수 연결 정보로 업데이트해야 합니다.

{
  "user": "my_user",
  "password": "my_password",
  "account": "my_account",
  "role": "my_role",
  "warehouse": "my_warehouse",
  "database": "my_database",
  "schema": "my_schema"
}

추가 권장 사항

SPRKPY1054

메시지: pyspark.sql.readwriter.DataFrameReader.format은 지원되지 않습니다.

카테고리: 경고.

설명

This issue appears when the pyspark.sql.readwriter.DataFrameReader.format has an argument that is not supported by Snowpark.

시나리오

There are some scenarios depending on the type of format you are trying to load. It can be a supported , or non-supported format.

시나리오 1

입력

이 도구는 로딩하려는 형식의 유형을 분석하며, 지원되는 형식은 다음과 같습니다.

  • Csv

  • JSON

  • Parquet

  • Orc

The below example shows how the tool transforms the format method when passing a Csv value.

from pyspark.sql import SparkSession
spark = SparkSession.builder.getOrCreate()

df1 = spark.read.format('csv').load('/path/to/file')

출력

The tool transforms the format method into a Csv method call.

from snowflake.snowpark import Session
spark = Session.builder.getOrCreate()

df1 = spark.read.csv('/path/to/file')

권장 수정

이 경우 도구에 EWI 가 표시되지 않으므로 수정할 필요가 없습니다.

시나리오 2

입력

The below example shows how the tool transforms the format method when passing a Jdbc value.

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

출력

The tool shows the EWI SPRKPY1054 indicating that the value “jdbc” is not supported.

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

권장 수정

For the not supported scenarios, there is no specific fix since it depends on the files that are trying to be read.

시나리오 3

입력

The below example shows how the tool transforms the format method when passing a CSV, but using a variable instead.

from snowflake.snowpark import Session
spark = Session.builder.getOrCreate()

myFormat = 'csv'
df3 = spark.read.format(myFormat).load('/path/to/file')

출력

Since the tool can not determine the value of the variable in runtime, shows the EWI SPRKPY1054 indicating that the value “” is not supported.

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

권장 수정

As a workaround, you can check the value of the variable and add it as a string to the format call.

추가 권장 사항

SPRKPY1055

메시지: pyspark.sql.readwriter.DataFrameReader.option 키 값은 지원되지 않습니다.

카테고리: 경고.

설명

This issue appears when the pyspark.sql.readwriter.DataFrameReader.option key value is not supported by SnowFlake.

이 도구는 옵션 호출 매개 변수를 분석하고 메서드(CSV 또는 JSON 또는 PARQUET)에 따라 키 값이 Snowpark에 해당하는 값이 있거나 없을 수 있으며, 모든 매개 변수에 해당하는 값이 있으면 도구는 EWI 를 추가하지 않고 해당 키 값으로 대체하고 그렇지 않으면 도구는 EWI 를 추가합니다.

동등 매개 기능 목록:

  • CSV 동등 기능:

Spark 옵션 키

Snowpark 동등 기능

sep

FIELD_DELIMITER

헤더

PARSE_HEADER

lineSep

RECORD_DELIMITER

pathGlobFilter

PATTERN

인용

FIELD_OPTIONALLY_ENCLOSED_BY

nullValue

NULL_IF

날짜 형식

DATE_FORMAT

타임스탬프 형식

TIMESTAMP_FORMAT

추론 스키마

INFER_SCHEMA

구분_기호

FIELD_DELIMITER

  • JSON 동등 기능:

Spark 옵션 키

Snowpark 동등 기능

날짜 형식

DATE_FORMAT

타임스탬프 형식

TIMESTAMP_FORMAT

pathGlobFilter

PATTERN

  • PARQUET 동등 기능:

Spark 옵션 키

Snowpark 동등 기능

pathGlobFilter

PATTERN

위 테이블에 없는 다른 키 옵션은 지원되지 않거나 Snowpark에 해당 옵션이 없습니다. 이 경우 도구는 매개 변수 정보와 함께 EWI 를 추가하고 체인에서 제거합니다.

시나리오

아래 시나리오는 CSV, JSON, PARQUET 에 적용됩니다.

There are a couple of scenarios depending on the value of the key used in the option method.

시나리오 1

입력

Below is an example of a option call using a equivalent key.

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)

출력

이 도구는 키를 올바른 등가물로 변환합니다.

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)

권장 수정

이 도구는 키의 값을 변환하므로 수정할 필요가 없습니다.

시나리오 2

입력

Below is an example of a option call using a non-equivalent key.

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)

출력

The tool adds the EWI SPRKPY1055 indicating the key is not supported and removes the option call.

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)

권장 수정

변환 후 동작을 확인하는 것이 좋습니다.

추가 권장 사항

  • 동등하지 않은 매개 변수가 있는 경우 변환 후 동작을 확인하는 것이 좋습니다.

  • For more support, you can email us at sma-support@snowflake.com or post an issue in the SMA.

SPRKPY1056

경고

이 문제 코드는 사용 중단 되었습니다

메시지: DataFrameReader.option 인자 _ <argument_name> _는 리터럴이 아니므로 평가할 수 없습니다

카테고리: 경고

설명

This issue appears when the argument’s key or value of the pyspark.sql.readwriter.DataFrameReader.option function is not a literal value (for example a variable). The SMA does a static analysis of your source code, and therefore it is not possible to evaluate the content of the argument.

시나리오

입력

Below is an example of a use of the pyspark.sql.readwriter.DataFrameReader.option function that generates this 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')

출력

The SMA adds the EWI SPRKPY1056 to the output code to let you know that the argument of this function is not a literal value, and therefore it could not be evaluated by the 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')

권장 수정

Even though the SMA was unable to evaluate the argument, it does not mean that it is not supported by Snowpark. Please make sure that the value of the argument is valid and equivalent in Snowpark by checking the documentation.

추가 권장 사항

SPRKPY1057

경고

This Issue Code has been deprecated since Spark Conversion Core Version 4.8.0

Message: PySpark Dataframe Option argument contains a value that is not a literal, therefore cannot be evaluated

카테고리: 경고.

설명

이 문제 코드는 더 이상 사용되지 않습니다. 이전 버전을 사용 중인 경우 최신 버전으로 업그레이드하십시오.

추가 권장 사항

SPRKPY1058

메시지: < 방법 > < 키 > 플랫폼별 키는 지원되지 않습니다.

카테고리: ConversionError

설명

The get and set methods from pyspark.sql.conf.RuntimeConfig are not supported with a Platform specific key.

시나리오

Not all usages of get or set methods are going to have an EWI in the output code. This EWI appears when the tool detects the usage of these methods with a Platform specific key which is not supported.

시나리오 1

입력

Below is an example of the get or set methods with supported keys in 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")

출력

Snowpark에서 키가 지원되므로 이 도구는 출력 코드에 EWI 를 추가하지 않습니다.

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

권장 수정

이 시나리오에 대한 권장 수정 사항은 없습니다.

시나리오 2

입력

아래는 지원되지 않는 키를 사용한 예제입니다.

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

출력

The tool adds this EWI SPRKPY1058 on the output code to let you know that these methods are not supported with a Platform specific key.

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

권장 수정

권장되는 수정 방법은 이러한 메서드를 제거하는 것입니다.

data =
    [
      ("John", 30, "New York"),
      ("Jane", 25, "San Francisco")
    ]

df = spark.createDataFrame(data, schema=["Name", "Age", "City"])

추가 권장 사항

SPRKPY1059

경고

This issue code has been deprecated since Spark Conversion Core Version 2.45.1

Message: pyspark.storagelevel.StorageLevel has a workaround, see documentation.

카테고리: 경고

설명

Currently, the use of StorageLevel is not required in Snowpark since Snowflake controls the storage. For more information, you can refer to the EWI SPRKPY1072

추가 권장 사항

SPRKPY1060

메시지: 인증 메커니즘은 connection.json(템플릿 제공)입니다.

카테고리: 경고.

설명

This issue appears when the tool detects the usage of pyspark.conf.SparkConf.

시나리오

입력

Snowpark에서는 인증 메커니즘이 다르므로 이 도구는 해당 사용처를 제거하고 대신 연결 구성 파일(connection.json) 을 생성합니다.

from pyspark import SparkConf

my_conf = SparkConf(loadDefaults=True)

출력

The tool adds the EWI SPRKPY1060 indicating that the authentication mechanism is different.

#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

권장 수정

To create a connection it is necessary that you fill in the information in the connection.json file.

{
  "user": "<USER>",
  "password": "<PASSWORD>",
  "account": "<ACCOUNT>",
  "role": "<ROLE>",
  "warehouse": "<WAREHOUSE>",
  "database": "<DATABASE>",
  "schema": "<SCHEMA>"
}

추가 권장 사항

SPRKPY1061

메시지: Snowpark는 unix_timestamp 함수를 지원하지 않습니다

카테고리: 경고

설명

In Snowpark, the first parameter is mandatory; the issue appears when the tool detects the usage of pyspark.sql.functions.unix_timestamp with no parameters.

시나리오

입력

Below an example that calls the unix_timestamp method without parameters.

data = [["2015-04-08", "10"],["2015-04-10", "15"]]

df = spark.createDataFrame(data, ['dt', 'val'])
df.select(unix_timestamp()).show()

출력

The Snowpark signature for this function unix_timestamp(e: ColumnOrName, fmt: Optional["Column"] = None), as you can notice the first parameter it’s required.

The tool adds this EWI SPRKPY1061 to let you know that function unix_timestamp with no parameters it’s not supported in 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()

권장 수정

해결 방법으로 최소한 타임스탬프 문자열의 이름이나 열을 추가할 수 있습니다.

data = [["2015-04-08", "10"],["2015-04-10", "15"]]

df = spark.createDataFrame(data, ["dt", "val"])
df.select(unix_timestamp("dt")).show()

추가 권장 사항

SPRKPY1062

메시지: Snowpark는 매개 변수 “values”가 없는 GroupedData.pivot을 지원하지 않습니다.

카테고리: 경고

설명

This issue appears when the SMA detects the usage of the pyspark.sql.group.GroupedData.pivot function without the “values” parameter (the list of values to pivot on).

현재 Snowpark Python 피벗 함수를 사용하려면 피벗할 고유 값 목록을 명시적으로 지정해야 합니다.

시나리오

시나리오 1

입력

The SMA detects an expression that matches the pattern dataFrame.groupBy("columnX").pivot("columnY") and the pivot does not have the values parameter.

df.groupBy("date").pivot("category").sum("amount")

출력

SMA 는 “values” 매개 변수가 없는 피벗 함수가 지원되지 않음을 나타내는 EWI 메시지를 추가합니다.

또한 피벗 함수의 두 번째 매개 변수로 열로 변환될 값의 목록을 계산하는 목록 이해도를 추가합니다. 이 작업은 대규모 데이터 세트에는 효율적이지 않으므로 값을 명시적으로 표시하는 것이 좋습니다.

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

권장 수정

이 시나리오에서는 SMA 피벗 함수의 두 번째 매개 변수에 열로 변환될 값의 목록을 계산하는 목록 이해력을 추가하지만 다음과 같이 피벗할 고유 값의 목록을 지정할 수 있습니다.

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")
시나리오 2

입력

The SMA couldn’t detect an expression that matches the pattern dataFrame.groupBy("columnX").pivot("columnY") and the pivot does not have the values parameter.

df1.union(df2).groupBy("date").pivot("category").sum("amount")

출력

SMA 는 “values” 매개 변수가 없는 피벗 함수가 지원되지 않음을 나타내는 EWI 메시지를 추가합니다.

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

권장 수정

다음과 같이 피벗할 고유 값 목록을 추가합니다.

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

추가 권장 사항

  • 피벗할 고유 값의 목록을 계산하는 것은 대규모 데이터 세트에서 효율적인 작업이 아니며 차단 호출이 될 수 있습니다. 피벗할 고유 값 목록을 명시적으로 표시하는 것을 고려해 보십시오.

  • 피벗할 고유 값 목록을 명시적으로 지정하지 않으려면(권장하지 않음), 다음 코드를 피벗 함수의 두 번째 인자로 추가하여 런타임에 값을 유추할 수 있습니다.*

[v[0] for v in <df>.select(<column>).distinct().limit(<count>).collect()]]

****Replace*** :code:`<df>` with the corresponding DataFrame, with the column to pivot and with the number of rows to select.

SPRKPY1063

메시지: pyspark.sql.pandas.functions.pandas_udf에 해결 방법이 있습니다.

카테고리: 경고

설명

This issue appears when the tool detects the usage of pyspark.sql.pandas.functions.pandas_udf which has a workaround.

시나리오

입력

Pandas_udf 함수는 대량의 데이터로 작동하는 사용자 정의 함수를 생성하는 데 사용됩니다.

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

출력

SMA 에는 EWI 메시지가 추가되어 pandas_udf에 해결 방법이 있음을 나타냅니다.

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

권장 수정

Specify explicitly the parameters types as a new parameter input_types, and remove functionType parameter if applies. Created function must be called inside a select statement.

@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

추가 권장 사항

SPRKPY1064

Message: The *Spark element* does not apply since snowflake uses snowpipe mechanism instead.

카테고리: 경고

설명

이 문제는 도구가 pyspark.streaming 라이브러리에서 어떤 요소의 사용을 감지할 때 표시됩니다.

시나리오

입력

아래는 이 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()

출력

The SMA adds the EWI SPRKPY1064 on the output code to let you know that this function does not apply.

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

권장 수정

The SMA removes the import statement and adds the issue to the Issues.csv inventory, remove any usages of the Spark element.

df = spark.createDataFrame([(25, "Alice", "150"), (30, "Bob", "350")], schema=["age", "name", "value"])
df.show()

추가 권장 사항

SPRKPY1065

메시지: Snowflake는 데이터 클러스터링 메커니즘을 사용하여 데이터를 계산하기 때문에 pyspark.context.SparkContext.broadcast는 적용되지 않습니다.

카테고리: 경고

설명

This issue appears when the tool detects the usage of element pyspark.context.SparkContext.broadcast, which is not necessary due to the use of data-clustering of Snowflake.

입력 코드

이 예제에서는 브로드캐스트 변수가 생성되며, 이 변수를 통해 모든 노드에서 데이터를 보다 효율적으로 공유할 수 있습니다.

sc = SparkContext(conf=conf_spark)

mapping = {1: 10001, 2: 10002}

bc = sc.broadcast(mapping)

출력 코드

SMA 는 브로드캐스트가 필요하지 않음을 나타내는 EWI 메시지를 추가합니다.

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)

권장 수정

SparkContext.broadcast.

sc = conf_spark

mapping = {1: 10001, 2: 10002}

추가 권장 사항

SPRKPY1066

메시지: Snowflake 사용 마이크로 파티션 메커니즘은 자동으로 생성되므로 Spark 요소는 적용되지 않습니다.

카테고리: 경고

설명

이 문제는 도구가 파티션과 관련된 요소의 사용을 감지할 때 표시됩니다.

Those elements do not apply due the use of micro-partitions of Snowflake.

입력 코드

In this example sortWithinPartitions it’s used to create a partition in a DataFrame sorted by the specified column.

df = spark.createDataFrame([(2, "Alice"), (5, "Bob")], schema=["age", "name"])
df.sortWithinPartitions("age", ascending=False)

출력 코드

SMA 에는 Spark 요소가 필수가 아님을 나타내는 EWI 메시지가 추가됩니다.

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)

권장 수정

요소의 사용법을 제거합니다.

df = spark.createDataFrame([(2, "Alice"), (5, "Bob")], schema=["age", "name"])

추가 권장 사항

SPRKPY1067

메시지: Pyspark.sql.functions.split에는 Snowpark에서 지원되지 않는 매개 변수가 있습니다.

카테고리: 경고

설명

This issue appears when the tool detects the usage of pyspark.sql.functions.split with more than two parameters or a regex pattern as a parameter; both cases are not supported.

시나리오

시나리오 1

입력 코드

이 예제에서 분할 함수에는 2개 이상의 매개 변수가 있습니다.

df.select(split(columnName, ",", 5))

출력 코드

도구는 출력 코드에 EWI 를 추가하여 2개 이상의 매개 변수가 있는 경우 이 함수가 지원되지 않음을 알려줍니다.

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

권장 수정

2개의 매개 변수만 사용하여 분할 함수를 유지합니다.

df.select(split(columnName, ","))
시나리오 2

입력 코드

이 예제에서 분할 함수에는 매개 변수로 정규식 패턴이 있습니다.

df.select(split(columnName, "^([\d]+-[\d]+-[\d])"))

출력 코드

이 도구는 출력 코드에 EWI 를 추가하여 이 함수가 매개 변수로 정규식 패턴이 있는 경우 지원되지 않음을 알려줍니다.

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

권장 수정

The spark signature for this method functions.split(str: ColumnOrName, pattern: str, limit: int = - 1) not exactly match with the method in Snowpark functions.split(str: Union[Column, str], pattern: Union[Column, str]) so for now the scenario using regular expression does not have a recommended fix.

추가 권장 사항

SPRKPY1068

메시지: toPandas에 지원되지 않는 ArrayType 형식의 열이 포함되어 있으며 해결 방법이 있습니다.

카테고리: 경고

설명

pyspark.sql.DataFrame.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.

시나리오

입력

ToPandas 는 원본 DataFrame 의 데이터를 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()

출력

이 도구는 ArrayType 유형의 열이 있는 경우 toPandas가 지원되지 않는다는 것을 알리기 위해 EWI 를 추가하지만 해결 방법이 있습니다.

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

권장 수정

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)

추가 권장 사항

SPRKPY1069

메시지: PartitionBy 매개 변수가 목록인 경우, Snowpark는 오류를 throw합니다.

카테고리: 경고

설명

When there is a usage of pyspark.sql.readwriter.DataFrameWriter.parquet method where it comes to the parameter partitionBy, the tool shows the EWI.

This is because in Snowpark the DataFrameWriter.parquet only supports a ColumnOrSqlExpr as a partitionBy parameter.

시나리오

시나리오 1

입력 코드:

이 시나리오에서 partitionBy 매개 변수는 목록이 아닙니다.

df = spark.createDataFrame([(25, "Alice", "150"), (30, "Bob", "350")], schema=["age", "name", "value"])

df.write.parquet(file_path, partitionBy="age")

출력 코드:

The tool adds the EWI SPRKPY1069 to let you know that Snowpark throws an error if parameter is a list.

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

권장 수정

There is not a recommended fix for this scenario because the tool always adds this EWI just in case the partitionBy parameter is a list. Remember that in Snowpark, only accepts cloud locations using a snowflake stage.

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"))
시나리오 2

입력 코드:

이 시나리오에서 partitionBy 매개 변수는 목록입니다.

df = spark.createDataFrame([(25, "Alice", "150"), (30, "Bob", "350")], schema=["age", "name", "value"])

df.write.parquet(file_path, partitionBy=["age", "name"])

출력 코드:

The tool adds the EWI SPRKPY1069 to let you know that Snowpark throws an error if parameter is a list.

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

권장 수정

If the value of the parameter is a list, then replace it with a ColumnOrSqlExpr.

df.write.parquet(file_path, partition_by = sql_expr("age || name"), format_type_options = dict(compression = "None"))

추가 권장 사항

SPRKPY1070

Message: The mode argument is transformed to overwrite, check the variable value and set the corresponding bool value.

카테고리: 경고

설명

다음의 사용법이 있는 경우:

The tool analyzes the parameter mode to determinate if the value is overwrite.

시나리오

시나리오 1

입력 코드

이 시나리오에서 도구는 모드 매개 변수가 해당 부울 값을 설정할 수 있음을 감지합니다.

df.write.csv(file_path, mode="overwrite")

출력 코드:

The SMA tool analyzes the mode parameter, determinate that the value is overwrite and set the corresponding bool value

df.write.csv(file_path, format_type_options = dict(compression = "None"), overwrite = True)

권장 수정

이 시나리오는 도구가 해당 변환을 수행했기 때문에 권장되는 수정 사항이 없습니다.

시나리오 2:

입력 코드

In this scenario the tool can not validate the value is overwrite.

df.write.csv(file_path, mode=myVal)

출력 코드:

SMA 는 모드 변수가 ‘overwrite’로 변환되었음을 나타내는 EWI 메시지를 추가하지만, 변수 값을 확인하고 올바른 부울 값을 설정하는 것이 좋다는 것을 알려주기 위한 것이기도 합니다.

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

권장 수정

Check for the value of the parameter mode and add the correct value for the parameter overwrite.

df.write.csv(file_path, format_type_options = dict(compression = "None"), overwrite = True)

추가 권장 사항

SPRKPY1071

메시지: pyspark.rdd.RDD.getNumPartitions 함수는 Snowpark에서 필수가 아닙니다. 따라서 모든 참조를 제거해야 합니다.

카테고리: 경고

설명

This issue appears when the tool finds the use of the pyspark.rdd.RDD.getNumPartitions function. Snowflake uses micro-partitioning mechanism, so the use of this function is not required.

시나리오

입력

getNumPartitions 은 RDD 에서 파티션의 수량을 반환합니다.

df = spark.createDataFrame([('2015-04-08',), ('5',), [Row(a=1, b="b")]], ['dt', 'num', 'row'])

print(df.getNumPartitions())

출력

이 도구는 EWI 를 추가하여 getNumPartitions 이 필수가 아님을 알려줍니다.

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

권장 수정

이 함수의 모든 사용을 제거합니다.

df = spark.createDataFrame([('2015-04-08',), ('5',), [Row(a=1, b="b")]], ['dt', 'num', 'row'])

추가 권장 사항

SPRKPY1072

메시지: Snowpark에서 StorageLevel 사용은 필수가 아닙니다.

카테고리: 경고.

설명

This issue appears when the tool finds the use of the StorageLevel class, which works like “flags” to set the storage level. Since Snowflake controls the storage, the use of this function is not required.

추가 권장 사항

SPRKPY1073

메시지: 매개 변수가 없거나 반환 유형 매개 변수가 없는 pyspark.sql.functions.udf는 지원되지 않습니다

카테고리: 경고.

설명

This issue appears when the tool detects the usage of pyspark.sql.functions.udf as function or decorator and is not supported in two specifics cases, when it has no parameters or return type parameter.

시나리오

시나리오 1

입력

Pyspark에서는 입력 또는 반환 유형 매개 변수 없이 사용자 정의 함수를 생성할 수 있습니다.

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

출력

Snowpark에는 Udf 함수에 대한 입력 및 반환 유형이 필요합니다. 공급자가 제공하지 않고 SMA 는 매개 변수를 사용할 수 없기 때문입니다.

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

권장 수정

To fix this scenario is required to add the import for the returns types of the input and output, and then the parameters of return*type and input_types[] on the udf function _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()
시나리오 2

PySpark 에서 매개 변수 없이 @udf 데코레이터를 사용할 수 있습니다

입력

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

출력

In Snowpark all the parameters of a udf decorator are required.

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

권장 수정

To fix this scenario is required to add the import for the returns types of the input and output, and then the parameters of return_type and input_types[] on the udf @udf decorator.

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

추가 권장 사항

SPRKPY1074

메시지: 파일에 들여쓰기(공백과 탭)가 섞여 있습니다.

카테고리: 구문 분석 오류.

설명

이 문제는 도구에서 파일에 들여쓰기가 혼합되어 있는 것을 감지할 때 표시됩니다. 즉, 파일에는 공백과 탭을 조합하여 코드 라인을 들여쓰기할 수 있습니다.

시나리오

입력

Pyspark에서는 공백과 탭을 혼합하여 ID 레벨을 지정할 수 있습니다.

def foo():
    x = 5 # spaces
    y = 6 # tab

출력

SMA 는 혼합 들여쓰기 마커를 처리할 수 없습니다. 이 항목이 Python 코드 파일 SMA 에서 감지되면 첫 라인에 EWI SPRKPY1074 를 추가합니다.

## 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

권장 수정

해결책은 모든 들여쓰기 기호를 동일하게 생성하는 것입니다.

def foo():
  x = 5 # tab
  y = 6 # tab

추가 권장 사항

SPRKPY1075

카테고리

경고.

설명

Parse_json은 스키마 유효성 검사를 적용하지 않으므로 스키마에 따라 필터링/검증해야 하는 경우 몇 가지 논리를 도입해야 할 수 있습니다.

입력

df.select(from_json(df.value, Schema))
df.select(from_json(schema=Schema, col=df.value))
df.select(from_json(df.value, Schema, option))

출력

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

함수 from_json의 경우 스키마는 실제로 추론을 위해 전달되지 않고 유효성 검사에 사용됩니다. 이 예시를 참조하십시오.

data = [
    ('{"name": "John", "age": 30, "city": "New York"}',),
    ('{"name": "Jane", "age": "25", "city": "San Francisco"}',)
]

df = spark.createDataFrame(data, ["json_str"])

예 1: 데이터 타입 적용 및 열 이름 변경:

## 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

예 2: 특정 열 선택:

## 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

권장 사항

  • For more support, you can email us at sma-support@snowflake.com. If you have a contract for support with Snowflake, reach out to your sales engineer and they can direct your support needs.

  • Useful tools PEP-8 and Reindent.

SPRKPY1076

Message: Parameters in pyspark.sql.readwriter.DataFrameReader methods are not supported. This applies to CSV, JSON and PARQUET methods.

카테고리: 경고.

설명

For the CSV, JSON and PARQUET methods on the pyspark.sql.readwriter.DataFrameReader object, the tool will analyze the parameters and add a transformation according to each case:

  • 모든 매개 변수는 Snowpark에서 해당 이름과 일치합니다. 이 경우 도구는 매개 변수를 .option() 호출로 변환합니다. 이 경우 매개 변수는 EWI 를 추가하지 않습니다.

  • 일부 매개 변수는 Snowpark의 해당 매개 변수와 일치하지 않습니다. 이 경우 도구는 EWI 매개 변수 정보를 추가하고 메서드 호출에서 제거합니다.

동등 매개 기능 목록:

  • CSV 동등 기능:

Spark 키

Snowpark 동등 기능

sep

FIELD_DELIMITER

헤더

PARSE_HEADER

lineSep

RECORD_DELIMITER

pathGlobFilter

PATTERN

인용

FIELD_OPTIONALLY_ENCLOSED_BY

nullValue

NULL_IF

날짜 형식

DATE_FORMAT

타임스탬프 형식

TIMESTAMP_FORMAT

추론 스키마

INFER_SCHEMA

구분_기호

FIELD_DELIMITER

  • JSON 동등 기능:

Spark 키

Snowpark 동등 기능

날짜 형식

DATE_FORMAT

타임스탬프 형식

TIMESTAMP_FORMAT

pathGlobFilter

PATTERN

  • PARQUET 동등 기능:

Spark 키

Snowpark 동등 기능

pathGlobFilter

PATTERN

시나리오

시나리오 1

입력

CVS 의 경우 몇 가지 예가 있습니다.

from pyspark.sql import SparkSession

spark = SparkSession.builder.appName('myapp').getOrCreate()

spark.read.csv("path3", None,None,None,None,None,None,True).show()

출력

변환된 코드에서 매개 변수는 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()

시나리오 2

입력

JSON 의 경우 몇 가지 예가 있습니다.

from pyspark.sql import SparkSession
spark = SparkSession.builder.appName('myapp').getOrCreate()
spark.read.json("/myPath/jsonFile/", dateFormat='YYYY/MM/DD').show()

출력

변환된 코드에서 매개 변수는 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()
시나리오 3

입력

PARQUET 의 경우 몇 가지 예가 있습니다.

from pyspark.sql import SparkSession
spark = SparkSession.builder.appName('myapp').getOrCreate()

spark.read.parquet("/path/to/my/file.parquet", pathGlobFilter="*.parquet").show()

출력

변환된 코드에서 매개 변수는 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")

추가 권장 사항

SPRKPY1077

메시지: SQL 임베디드 코드를 처리할 수 없습니다.

카테고리: 경고.

설명

이 문제는 도구에서 Snowpark로 변환할 수 없는 SQL 임베디드 코드를 감지할 때 표시됩니다.

자세한 내용은 SQL 임베디드 코드 섹션을 참조하십시오.

시나리오

입력

이 예제에서는 SQL 코드가 Pyspark.sql 메서드의 매개 변수로 사용되는 쿼리라는 변수에 포함되어 있습니다.

query = f"SELECT * from myTable"
spark.sql(query)

출력

SMA 는 PySpark.sql 매개 변수가 SQL 코드가 아닌 변수임을 감지하여 EWI SPRKPY1077 메시지가 PySpark.sql 라인에 추가됩니다.

query = f"SELECT * myTable"
#EWI: SPRKPY1077 => SQL embedded code cannot be processed.
spark.sql(query)

추가 권장 사항

  • SQL 의 변환을 위해 이 코드는 보간 없이 문자열 값으로만 메서드의 매개 변수로 직접 내부에 있어야 합니다. Snowflake에서 기능을 확인하려면 PySpark.SQL 함수로 보내기를 확인하십시오.

  • For more support, you can email us at sma-support@snowflake.com or post an issue in the SMA.

SPRKPY1078

메시지: SparkContext.setLogLevel 함수의 인자가 리터럴 값이 아니므로 평가할 수 없습니다

카테고리: 경고

설명

This issue appears when the SMA detects the use of the pyspark.context.SparkContext.setLogLevel function with an argument that is not a literal value, for example, when the argument is a variable.

SMA 는 소스 코드의 정적 분석을 수행하므로 해당 인자의 내용을 평가하여 Snowpark에서 동등한 것을 결정할 수 없습니다.

시나리오

입력

이 예제에서는 로그 레벨을 my_log_level 변수에 정의한 다음 setLogLevel 메서드에서 my_log_level을 매개 변수로 사용합니다.

my_log_level = "WARN"
sparkSession.sparkContext.setLogLevel(my_log_level)

출력

SMA 가 로그 수준 매개 변수의 인자를 평가할 수 없으므로 변환된 로깅 라인에 EWI SPRKPY1078 이 추가됩니다.

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)

권장 수정

Even though the SMA was unable to evaluate the argument, it will transform the pyspark.context.SparkContext.setLogLevel function into the Snowpark equivalent. Please make sure the value of the level argument in the generated output code is a valid and equivalent log level in Snowpark according to the table below:

PySpark 로그 수준

Snowpark 로그 수준 동등 기능

ALL

logging.NOTSET

DEBUG

logging.DEBUG

ERROR

logging.ERROR

FATAL

logging.CRITICAL

INFO

logging.INFO

OFF

logging.WARNING

TRACE

logging.NOTSET

WARN

logging.WARNING

따라서 권장 수정 사항은 다음과 같습니다.

my_log_level = logging.WARNING
logging.basicConfig(stream = sys.stdout, level = my_log_level)

추가 권장 사항

SPRKPY1079

메시지: SparkContext.setLogLevel 함수의 인자가 유효한 PySpark 로그 수준이 아닙니다

카테고리: 경고

설명

This issue appears when the SMA detects the use of the pyspark.context.SparkContext.setLogLevel function with an argument that is not a valid log level in PySpark, and therefore an equivalent could not be determined in Snowpark.

시나리오

입력

여기서 로그 수준은 유효한 Pyspark 로그 수준이 아닌 “INVALID_LOG_LEVEL”을 사용합니다.

sparkSession.sparkContext.setLogLevel("INVALID_LOG_LEVEL")

출력

SMA 가 로깅 수준 “INVALID_LOG_LEVEL”을 인식할 수 없는 경우, SMA 가 변환을 수행하더라도 EWI SPRKPY1079 가 추가되어 문제가 있을 수 있음을 나타냅니다.

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

권장 수정

Make sure that the log level used in the pyspark.context.SparkContext.setLogLevel function is a valid log level in PySpark or in Snowpark and try again.

logging.basicConfig(stream = sys.stdout, level = logging.DEBUG)

추가 권장 사항

SPRKPY1081

This issue code has been deprecated since Spark Conversion Core 4.12.0

메시지: pyspark.sql.readwriter.DataFrameWriter.partitionBy에 해결 방법이 있습니다.

카테고리: 경고

설명

The Pyspark.sql.readwriter.DataFrameWriter.partitionBy function is not supported. The workaround is to use Snowpark’s copy_into_location instead. See the documentation for more info.

시나리오

입력

This code will create a separate directories for each unique value in the FIRST_NAME column. The data is the same, but it’s going to be stored in different directories based on the column.

df = session.createDataFrame([["John", "Berry"], ["Rick", "Berry"], ["Anthony", "Davis"]], schema = ["FIRST_NAME", "LAST_NAME"])
df.write.partitionBy("FIRST_NAME").csv("/home/data")

This code will create a separate directories for each unique value in the FIRST_NAME column. The data is the same, but it’s going to be stored in different directories based on the column.

출력 코드

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

권장 수정

In Snowpark, copy_into_location has a partition_by parameter that you can use instead of the partitionBy function, but it’s going to require some manual adjustments, as shown in the following example:

Spark 코드:

df = session.createDataFrame([["John", "Berry"], ["Rick", "Berry"], ["Anthony", "Davis"]], schema = ["FIRST_NAME", "LAST_NAME"])
df.write.partitionBy("FIRST_NAME").csv("/home/data")

Snowpark 코드를 수동으로 조정:

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 에는 다음 매개 변수가 있습니다

  • location: The Snowpark location only accepts cloud locations using an snowflake stage.

  • _partition_by_: 열 이름 또는 SQL 식일 수 있으므로 col 또는 sql_expr을 사용하여 열 또는 SQL 로 변환해야 합니다.

추가 권장 사항

SPRKPY1082

메시지: DataFrameReader.load 함수는 지원되지 않습니다. 해결 방법은 대신 Snowpark DataFrameReader 형식별 메서드(avro csv, json, orc, parquet)를 사용하는 것입니다. 경로 매개 변수는 스테이지 위치여야 합니다.

카테고리: 경고

설명

The pyspark.sql.readwriter.DataFrameReader.load function is not supported. The workaround is to use Snowpark DataFrameReader methods instead.

시나리오

The spark signature for this method DataFrameReader.load(path, format, schema, **options) does not exist in Snowpark. Therefore, any usage of the load function is going to have an EWI in the output code.

시나리오 1

입력

Below is an example that tries to load data from a CSV source.

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

출력

The SMA adds the EWI SPRKPY1082 to let you know that this function is not supported by Snowpark, but it has a workaround.

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

권장 수정

As a workaround, you can use Snowpark DataFrameReader methods instead.

  • Fixing path and format parameters:

    • Replace the load method with csv method.

    • The first parameter path must be in a stage to make an equivalence with Snowpark.

Below is an example that creates a temporal stage and puts the file into it, then calls the CSV method.

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()
  • Fixing schema parameter:

    • The schema can be set by using the schema function as follows:

schemaParam = StructType([
        StructField("name", StringType(), True),
        StructField("city", StringType(), True)
    ])

df = my_session.read.schema(schemaParam).csv(temp_stage)
  • Fixing options parameter:

The options between spark and snowpark are not the same, in this case lineSep and dateFormat are replaced with RECORD_DELIMITER and DATE_FORMAT, the Additional recommendations section has a table with all the Equivalences.

Below is an example that creates a dictionary with RECORD_DELIMITER and DATE_FORMAT, and calls the options method with that dictionary.

optionsParam = {"RECORD_DELIMITER": "\r\n", "DATE_FORMAT": "YYYY/MM/DD"}
df = my_session.read.options(optionsParam).csv(stage)

시나리오 2

입력

Below is an example that tries to load data from a JSON source.

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

출력

The SMA adds the EWI SPRKPY1082 to let you know that this function is not supported by Snowpark, but it has a workaround.

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

권장 수정

As a workaround, you can use Snowpark DataFrameReader methods instead.

  • Fixing path and format parameters:

    • Replace the load method with json method

    • The first parameter path must be in a stage to make an equivalence with Snowpark.

Below is an example that creates a temporal stage and puts the file into it, then calls the JSON method.

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()
  • Fixing schema parameter:

    • The schema can be set by using the schema function as follows:

schemaParam = StructType([
        StructField("name", StringType(), True),
        StructField("city", StringType(), True)
    ])

df = my_session.read.schema(schemaParam).json(temp_stage)
  • Fixing options parameter:

The options between Spark and snowpark are not the same, in this case dateFormat and timestampFormat are replaced with DATE_FORMAT and TIMESTAMP_FORMAT, the Additional recommendations section has a table with all the Equivalences.

Below is an example that creates a dictionary with DATE_FORMAT and TIMESTAMP_FORMAT, and calls the options method with that dictionary.

optionsParam = {"DATE_FORMAT": "YYYY/MM/DD", "TIMESTAMP_FORMAT": "YYYY-MM-DD HH24:MI:SS.FF3"}
df = Session.read.options(optionsParam).json(stage)

시나리오 3

입력

Below is an example that tries to load data from a PARQUET source.

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

출력

The SMA adds the EWI SPRKPY1082 to let you know that this function is not supported by Snowpark, but it has a workaround.

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

권장 수정

As a workaround, you can use Snowpark DataFrameReader methods instead.

  • Fixing path and format parameters:

    • Replace the load method with parquet method

    • The first parameter path must be in a stage to make an equivalence with Snowpark.

Below is an example that creates a temporal stage and puts the file into it, then calls the PARQUET method.

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()
  • Fixing schema parameter:

    • The schema can be set by using the schema function as follows:

schemaParam = StructType([
        StructField("name", StringType(), True),
        StructField("city", StringType(), True)
    ])

df = my_session.read.schema(schemaParam).parquet(temp_stage)
  • Fixing options parameter:

The options between Spark and snowpark are not the same, in this case pathGlobFilter is replaced with PATTERN, the Additional recommendations section has a table with all the Equivalences.

Below is an example that creates a dictionary with PATTERN, and calls the options method with that dictionary.

optionsParam = {"PATTERN": "*.parquet"}
df = Session.read.options(optionsParam).parquet(stage)

추가 권장 사항

  • Spark와 Snowpark의 옵션은 동일하지 않지만 매핑이 가능하다는 점을 고려하십시오.

Spark 옵션

가능한 값

Snowpark 등가물

설명

헤더

true 또는 false

SKIP_HEADER = 1 / SKIP_HEADER = 0

파일의 첫 라인을 열 이름으로 사용하려면 다음과 같이 하십시오.

구분_기호

모든 단일/다중 문자 필드 구분 기호

FIELD_DELIMITER

각 열/필드에 단일/복수의 문자를 구분 기호로 지정합니다.

sep

단일 문자 필드 구분 기호

FIELD_DELIMITER

각 열/필드에 단일 문자를 구분 기호로 지정합니다.

인코딩

UTF-8, UTF-16 등…

ENCODING

지정된 인코딩 유형으로 CSV 파일을 디코딩합니다. 기본 인코딩은 UTF-8입니다

lineSep

단일 문자 라인 바꿈 기호

RECORD_DELIMITER

파일 구문 분석에 사용할 라인 바꿈 구분자를 정의합니다.

pathGlobFilter

파일 패턴

PATTERN

패턴과 일치하는 파일 이름만 읽도록 패턴을 정의합니다.

recursiveFileLookup

true 또는 false

N/A

디렉터리를 재귀적으로 스캔하여 파일을 읽으려면. 이 옵션의 기본값은 false입니다.

인용

작은따옴표로 묶을 1개 문자

FIELD_OPTIONALLY_ENCLOSED_BY

구분 기호/숫자가 값의 일부가 될 수 있는 필드가 포함된 필드/열을 인용하려면. QuoteAll 옵션과 함께 사용할 때 모든 필드를 인용하려면 이 문자를 입력합니다. 이 옵션의 기본값은 큰따옴표(“)입니다.

nullValue

Null을 대체할 문자열

NULL_IF

데이터프레임을 읽고 쓰는 동안 문자열을 null 값으로 바꿉니다.

날짜 형식

유효한 날짜 형식

DATE_FORMAT

날짜 형식을 나타내는 문자열을 정의합니다. 기본 형식은 yyyy-MM-dd입니다.

타임스탬프 형식

유효한 타임스탬프 형식

TIMESTAMP_FORMAT

타임스탬프 형식을 나타내는 문자열을 정의합니다. 기본 형식은 yyyy-MM-dd’T’HH:mm:ss입니다.

이스케이프

모든 단일 문자

ESCAPE

단일 문자를 이스케이프 문자(\)로 설정하여 기본 이스케이프 문자를 재정의하려면.

추론 스키마

true 또는 false

INFER_SCHEMA

파일 스키마 자동 감지

mergeSchema

true 또는 false

N/A

이는 infer_schema가 Parquet 파일 구조를 결정할 때마다 발생하므로 Snowflake에서는 필요하지 않습니다

  • For modifiedBefore / modifiedAfter option you can achieve the same result in Snowflake by using the metadata columns and then adding a filter like: df.filter(METADATA_FILE_LAST_MODIFIED > ‘some_date’).

  • For more support, you can email us at sma-support@snowflake.com or post an issue in the SMA.

SPRKPY1083

메시지: DataFrameWriter.save 함수는 지원되지 않습니다. 해결 방법은 대신 Snowpark DataFrameWriter copy_into_location 메서드를 사용하는 것입니다.

카테고리: 경고

설명

The pyspark.sql.readwriter.DataFrameWriter.save function is not supported. The workaround is to use Snowpark DataFrameWriter methods instead.

시나리오

The spark signature for this method DataFrameWriter.save(path, format, mode, partitionBy, **options) does not exists in Snowpark. Therefore, any usage of the load function it’s going to have an EWI in the output code.

시나리오 1

입력 코드

Below is an example that tries to save data with CSV format.

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

출력 코드

The tool adds this EWI SPRKPY1083 on the output code to let you know that this function is not supported by Snowpark, but it has a workaround.

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

권장 수정

As a workaround you can use Snowpark DataFrameWriter methods instead.

  • Fixing path and format parameters:

    • Replace the load method with csv or copy_into_location method.

    • If you are using copy_into_location method, you need to specify the format with the file_format_type parameter.

    • The first parameter path must be in a stage to make an equivalence with Snowpark.

아래는 임시 스테이지를 생성하고 그 안에 파일을 넣은 다음 위에서 언급한 메서드 중 하나를 호출하는 예제입니다.

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

Below is an example that adds into the daisy chain the mode method with overwrite as a parameter.

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")
  • Fixing partitionBy parameter:

    • Use the partition_by parameter from the CSV method, as follows:

Below is an example that used the partition_by parameter from the CSV method.

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")
  • Fixing options parameter:

The options between spark and snowpark are not the same, in this case lineSep and dateFormat are replaced with RECORD_DELIMITER and DATE_FORMAT, the Additional recommendations section has table with all the Equivalences.

Below is an example that creates a dictionary with RECORD_DELIMITER and DATE_FORMAT, and calls the options method with that dictionary.

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)

시나리오 2

입력 코드

Below is an example that tries to save data with JSON format.

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

출력 코드

The tool adds this EWI SPRKPY1083 on the output code to let you know that this function is not supported by Snowpark, but it has a workaround.

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

권장 수정

As a workaround you can use Snowpark DataFrameReader methods instead.

  • Fixing path and format parameters:

    • Replace the load method with json or copy_into_location method

    • If you are using copy_into_location method, you need to specify the format with the file_format_type parameter.

    • The first parameter path must be in a stage to make an equivalence with Snowpark.

아래는 임시 스테이지를 생성하고 그 안에 파일을 넣은 다음 위에서 언급한 메서드 중 하나를 호출하는 예제입니다.

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

Below is an example that adds into the daisy chain the mode method with overwrite as a parameter.

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")
  • Fixing partitionBy parameter:

    • Use the partition_by parameter from the CSV method, as follows:

Below is an example that used the partition_by parameter from the CSV method.

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")
  • Fixing options parameter:

The options between spark and snowpark are not the same, in this case dateFormat and timestampFormat are replaced with DATE_FORMAT and TIMESTAMP_FORMAT, the Additional recommendations section has table with all the Equivalences.

Below is an example that creates a dictionary with DATE_FORMAT and TIMESTAMP_FORMAT, and calls the options method with that dictionary.

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)

시나리오 3

입력 코드

Below is an example that tries to save data with PARQUET format.

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

출력 코드

The tool adds this EWI SPRKPY1083 on the output code to let you know that this function is not supported by Snowpark, but it has a workaround.

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

권장 수정

As a workaround you can use Snowpark DataFrameReader methods instead.

  • Fixing path and format parameters:

    • Replace the load method with parquet or copy_into_location method.

    • If you are using copy_into_location method, you need to specify the format with the file_format_type parameter.

    • The first parameter path must be in a stage to make an equivalence with Snowpark.

아래는 임시 스테이지를 생성하고 그 안에 파일을 넣은 다음 위에서 언급한 메서드 중 하나를 호출하는 예제입니다.

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

Below is an example that adds into the daisy chain the mode method with overwrite as a parameter.

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")
  • Fixing partitionBy parameter:

    • Use the partition_by parameter from the CSV method, as follows:

Below is an example that used the partition_by parameter from the parquet method.

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")
  • Fixing options parameter:

The options between spark and snowpark are not the same, in this case pathGlobFilter is replaced with PATTERN, the Additional recommendations section has table with all the Equivalences.

Below is an example that creates a dictionary with PATTERN, and calls the options method with that dictionary.

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)

추가 권장 사항

  • Spark와 Snowpark의 옵션은 동일하지 않지만 매핑할 수 있습니다.

Spark 옵션

가능한 값

Snowpark 등가물

설명

헤더

true 또는 false

SKIP_HEADER = 1 / SKIP_HEADER = 0

파일의 첫 라인을 열 이름으로 사용하려면 다음과 같이 하십시오.

구분_기호

모든 단일/다중 문자 필드 구분 기호

FIELD_DELIMITER

각 열/필드에 단일/복수의 문자를 구분 기호로 지정합니다.

sep

단일 문자 필드 구분 기호

FIELD_DELIMITER

각 열/필드에 단일 문자를 구분 기호로 지정합니다.

인코딩

UTF-8, UTF-16 등…

ENCODING

지정된 인코딩 유형으로 CSV 파일을 디코딩합니다. 기본 인코딩은 UTF-8입니다

lineSep

단일 문자 라인 바꿈 기호

RECORD_DELIMITER

파일 구문 분석에 사용할 라인 바꿈 구분자를 정의합니다.

pathGlobFilter

파일 패턴

PATTERN

패턴과 일치하는 파일 이름만 읽도록 패턴을 정의합니다.

recursiveFileLookup

true 또는 false

N/A

디렉터리를 재귀적으로 스캔하여 파일을 읽으려면. 이 옵션의 기본값은 false입니다.

인용

작은따옴표로 묶을 1개 문자

FIELD_OPTIONALLY_ENCLOSED_BY

구분 기호/숫자가 값의 일부가 될 수 있는 필드가 포함된 필드/열을 인용하려면. QuoteAll 옵션과 함께 사용할 때 모든 필드를 인용하려면 이 문자를 입력합니다. 이 옵션의 기본값은 큰따옴표(“)입니다.

nullValue

Null을 대체할 문자열

NULL_IF

데이터프레임을 읽고 쓰는 동안 문자열을 null 값으로 바꿉니다.

날짜 형식

유효한 날짜 형식

DATE_FORMAT

날짜 형식을 나타내는 문자열을 정의합니다. 기본 형식은 yyyy-MM-dd입니다.

타임스탬프 형식

유효한 타임스탬프 형식

TIMESTAMP_FORMAT

타임스탬프 형식을 나타내는 문자열을 정의합니다. 기본 형식은 yyyy-MM-dd’T’HH:mm:ss입니다.

이스케이프

모든 단일 문자

ESCAPE

단일 문자를 이스케이프 문자(\)로 설정하여 기본 이스케이프 문자를 재정의하려면.

추론 스키마

true 또는 false

INFER_SCHEMA

파일 스키마 자동 감지

mergeSchema

true 또는 false

N/A

이는 infer_schema가 Parquet 파일 구조를 결정할 때마다 발생하므로 Snowflake에서는 필요하지 않습니다

  • For modifiedBefore / modifiedAfter option you can achieve the same result in Snowflake by using the metadata columns and then add a filter like: df.filter(METADATA_FILE_LAST_MODIFIED > ‘some_date’).

  • For more support, you can email us at sma-support@snowflake.com or post an issue in the SMA.

SPRKPY1084

This issue code has been deprecated since Spark Conversion Core 4.12.0

메시지: pyspark.sql.readwriter.DataFrameWriter.option은 지원되지 않습니다.

카테고리: 경고

설명

The pyspark.sql.readwriter.DataFrameWriter.option function is not supported.

시나리오

입력 코드

Below is an example using the option method, this method is used to add additional configurations when writing the data of a 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)

출력 코드

The tool adds this EWI SPRKPY1084 on the output code to let you know that this function is not supported by 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)

권장 수정

DataFrameWriter.option 메서드에는 권장 수정 사항이 없습니다.

추가 권장 사항

SPRKPY1085

메시지: pyspark.ml.feature.VectorAssembler 는 지원되지 않습니다.

카테고리: 경고

설명

The pyspark.ml.feature.VectorAssembler is not supported.

시나리오

입력 코드

VectorAssembler 는 여러 열을 단일 벡터로 결합하는 데 사용됩니다.

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

출력 코드

The tool adds this EWI SPRKPY1085 on the output code to let you know that this class is not supported by 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")

권장 수정

pyspark.ml.feature.VectorAssembler 에는 권장 수정 사항이 없습니다.

추가 권장 사항

SPRKPY1086

메시지: pyspark.ml.linalg.VectorUDT 가 지원되지 않습니다.

카테고리: 경고

설명

The pyspark.ml.linalg.VectorUDT is not supported.

시나리오

입력 코드

VectorUDT 는 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)

출력 코드

The tool adds this EWI SPRKPY1086 on the output code to let you know that this function is not supported by 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)

권장 수정

VectorUDT 에는 권장 수정 사항이 없습니다.

추가 권장 사항

SPRKPY1087

메시지: DataFrame.writeTo 함수는 지원되지 않지만 해결 방법이 있습니다.

카테고리: 경고.

설명

The pyspark.sql.dataframe.DataFrame.writeTo function is not supported. The workaround is to use Snowpark DataFrameWriter SaveAsTable method instead.

시나리오

입력

Below is an example of a use of the pyspark.sql.dataframe.DataFrame.writeTo function, the dataframe df is written into a table name Personal_info.

df = spark.createDataFrame([["John", "Berry"], ["Rick", "Berry"], ["Anthony", "Davis"]],
                                 schema=["FIRST_NAME", "LAST_NAME"])

df.writeTo("Personal_info")

출력

The SMA adds the EWI SPRKPY1087 to the output code to let you know that this function is not supported, but has a workaround.

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

권장 수정

해결 방법은 대신 Snowpark DataFrameWriter SaveAsTable 메서드를 사용하는 것입니다.

df = spark.createDataFrame([["John", "Berry"], ["Rick", "Berry"], ["Anthony", "Davis"]],
                                 schema=["FIRST_NAME", "LAST_NAME"])

df.write.saveAsTable("Personal_info")

추가 권장 사항

SPRKPY1088

메시지: The pyspark.sql.readwriter.DataFrameWriter.option values in Snowpark may be different, so required validation might be needed.

카테고리: 경고

설명

The pyspark.sql.readwriter.DataFrameWriter.option values in Snowpark may be different, so validation might be needed to ensure that the behavior is correct.

시나리오

지원되는 옵션 또는 파일 작성에 사용되는 형식에 따라 몇 가지 시나리오가 있습니다.

시나리오 1

입력

Below is an example of the usage of the method option, adding a sep option, which is currently supported.

df = spark.createDataFrame([(100, "myVal")], ["ID", "Value"])

df.write.option("sep", ",").csv("some_path")

출력

The tool adds the EWI SPRKPY1088 indicating that it is required validation.

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

권장 수정

Snowpark API 는 이 매개 변수를 지원하므로 마이그레이션 후 동작을 확인하는 작업만 수행하면 됩니다. 지원되는 매개 변수를 확인하려면 동등성 테이블 을 참조하십시오.

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")
시나리오 2

입력

Here the scenario shows the usage of option, but adds a header option, which is not supported.

df = spark.createDataFrame([(100, "myVal")], ["ID", "Value"])

df.write.option("header", True).csv("some_path")

출력

The tool adds the EWI SPRKPY1088 indicating that it is required validation is needed.

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

권장 수정

For this scenario it is recommended to evaluate the Snowpark format type options to see if it is possible to change it according to your needs. Also, check the behavior after the change.

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")
시나리오 3

입력

This scenario adds a sep option, which is supported and uses the JSON method.

  • Note: this scenario also applies for PARQUET.

df = spark.createDataFrame([(100, "myVal")], ["ID", "Value"])

df.write.option("sep", ",").json("some_path")

출력

The tool adds the EWI SPRKPY1088 indicating that it is required validation is needed.

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

권장 수정

The file format JSON does not support the parameter sep, so it is recommended to evaluate the snowpark format type options to see if it is possible to change it according to your needs. Also, check the behavior after the change.

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

추가 권장 사항

  • Since there are some not supported parameters, it is recommended to check the table of equivalences and check the behavior after the transformation.

  • 동등 매개 변수 테이블:

PySpark 옵션

SnowFlake 옵션

지원되는 파일 형식

설명

SEP

FIELD_DELIMITER

CSV

입력 파일에서 필드를 구분하는 1개 이상의 단일 바이트 또는 멀티바이트 문자입니다.

LINESEP

RECORD_DELIMITER

CSV

입력 파일에서 레코드를 구분하는 하나 이상의 문자입니다.

QUOTE

FIELD_OPTIONALLY_ENCLOSED_BY

CSV

문자열을 묶는 데 사용되는 문자입니다.

NULLVALUE

NULL_IF

CSV

SQL NULL로 변환하거나 그 반대로 변환하는 데 사용되는 문자열입니다.

DATEFORMAT

DATE_FORMAT

CSV

로딩할 데이터 파일의 날짜 값 형식을 정의하는 문자열입니다.

TIMESTAMPFORMAT

TIMESTAMP_FORMAT

CSV

로딩할 데이터 파일의 타임스탬프 값 형식을 정의하는 문자열입니다.

사용되는 매개 변수가 목록에 없으면 API 가 오류를 throw합니다.

SPRKPY1089

메시지: The pyspark.sql.readwriter.DataFrameWriter.options values in Snowpark may be different, so required validation might be needed.

카테고리: 경고

설명

The pyspark.sql.readwriter.DataFrameWriter.options values in Snowpark may be different, so validation might be needed to ensure that the behavior is correct.

시나리오

옵션의 지원 여부 또는 파일 작성에 사용되는 형식에 따라 몇 가지 시나리오가 있습니다.

시나리오 1

입력

Below is an example of the usage of the method options, adding the options sep and nullValue, which are currently supported.

df = spark.createDataFrame([(1, "myVal")], [2, "myVal2"], [None, "myVal3" ])

df.write.options(nullValue="myVal", sep=",").csv("some_path")

출력

The tool adds the EWI SPRKPY1089 indicating that it is required validation.

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

권장 수정

Snowpark API 는 이러한 매개 변수를 지원하므로 마이그레이션 후 동작을 확인하는 작업만 하면 됩니다. 지원되는 매개 변수를 확인하려면 동등성 테이블 을 참조하십시오.

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")
시나리오 2

입력

Here the scenario shows the usage of options, but adds a header option, which is not supported.

df = spark.createDataFrame([(1, "myVal")], [2, "myVal2"], [None, "myVal3" ])

df.write.options(header=True, sep=",").csv("some_path")

출력

The tool adds the EWI SPRKPY1089 indicating that it is required validation is needed.

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

권장 수정

For this scenario it is recommended to evaluate the Snowpark format type options to see if it is possible to change it according to your needs. Also, check the behavior after the change.

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")
시나리오 3

입력

This scenario adds a sep option, which is supported and uses the JSON method.

df = spark.createDataFrame([(1, "myVal")], [2, "myVal2"], [None, "myVal3" ])

df.write.options(nullValue="myVal", sep=",").json("some_path")

출력

The tool adds the EWI SPRKPY1089 indicating that it is required validation is needed.

  • Note: this scenario also applies for 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")

권장 수정

The file format JSON does not support the parameter sep, so it is recommended to evaluate the snowpark format type options to see if it is possible to change it according to your needs. Also, check the behavior after the change.

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

추가 권장 사항

  • Since there are some not supported parameters, it is recommended to check the table of equivalences and check the behavior after the transformation.

  • 동등 매개 변수 테이블:

Snowpark는 일부 매개 변수에 대해 동등 매개 변수 목록을 지원할 수 있습니다.

PySpark 옵션

SnowFlake 옵션

지원되는 파일 형식

설명

SEP

FIELD_DELIMITER

CSV

입력 파일에서 필드를 구분하는 1개 이상의 단일 바이트 또는 멀티바이트 문자입니다.

LINESEP

RECORD_DELIMITER

CSV

입력 파일에서 레코드를 구분하는 하나 이상의 문자입니다.

QUOTE

FIELD_OPTIONALLY_ENCLOSED_BY

CSV

문자열을 묶는 데 사용되는 문자입니다.

NULLVALUE

NULL_IF

CSV

SQL NULL로 변환하거나 그 반대로 변환하는 데 사용되는 문자열입니다.

DATEFORMAT

DATE_FORMAT

CSV

로딩할 데이터 파일의 날짜 값 형식을 정의하는 문자열입니다.

TIMESTAMPFORMAT

TIMESTAMP_FORMAT

CSV

로딩할 데이터 파일의 타임스탬프 값 형식을 정의하는 문자열입니다.

사용되는 매개 변수가 목록에 없으면 API 가 오류를 throw합니다.

SPRKPY1101

카테고리

구문 분석 오류가 발생했습니다.

설명

도구가 구문 분석 오류를 인식하면 이를 복구하려고 시도하고 다음 라인에서 프로세스를 계속 진행합니다. 이러한 경우 해당 라인에 오류와 설명이 표시됩니다.

이 예는 공백과 탭 간의 불일치 오류를 처리하는 방법을 보여줍니다.

입력 코드

def foo():
    x = 5 # Spaces
     y = 6 # Tab

def foo2():
    x=6
    y=7

출력 코드

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

권장 사항

  • 설명이 달린 라인을 수정해 보십시오.

  • For more support, email us at sma-support@snowflake.com. If you have a support contract with Snowflake, reach out to your sales engineer, who can direct your support needs.