0
0

Databricks (Spark) にて dropduplicate や join にてエスケープ文字であるシングルクォートを指定した際のエラーへの対応方法

Posted at

概要

Databricks (Spark) にて dropduplicate や join にてエスケープ文字であるシングルクォートを指定した際のエラーへの対応方法を共有します。日本語のカラム(例:名前)を Spark の SQL で扱う際にはシングルクォートを指定する必要があるのですが、 dropduplicate や join などを利用する際にシングルクォートを指定すると下記のようなエラーが発生します。

AnalysisException: Cannot resolve column name "名前" among (名前, 数値).

image.png

AnalysisException: [UNRESOLVED_USING_COLUMN_FOR_JOIN] USING column 名前 cannot be resolved on the left side of the join. The left-side columns: [名前, 数値].

image.png

対応方法としては、dropduplicate や join を実行する際には、シングルクォートを TRIM する方法です。

col_list = ["`名前`"]
trimed_col_list = [col.lstrip("`").rstrip("`") for col in col_list]
df.dropDuplicates(trimed_col_list).display()

image.png

2024/06/04 時点にて、selectメソッドではエラーとならないがdropDuplicatesメソッドでエラーとなる原因を把握できておりませんが、自分のコードを見返した際に上記のような TRIM 処理を実施している理由を思い返せないため、備忘録として記事にします。Github Copilot から下記のような回答がでましたが、明確な理由を追えておりません。

Apache SparkにおけるselectメソッドとdropDuplicatesメソッドの動作の違いにより、この現象が起こります。

selectメソッドでは、引数として与えられた文字列をそのままカラム名として解釈します。したがって、バッククオート(``)を含む文字列もカラム名として解釈されます。

一方、dropDuplicatesメソッドでは、引数として与えられた文字列をバッククオート()なしのカラム名として解釈します。したがって、バッククオート()を含む文字列を引数として与えると、該当するカラム名が見つからないためエラーが発生します。

これらの違いは、PythonのPandasライブラリやSQLのようなデータ操作の抽象化を提供するApache Sparkの仕様に由来します。これらのメソッドは、様々なデータ操作の一部として設計されており、それぞれが異なるコンテキストで使用されるため、同じ引数が異なる解釈をされることがあります。

したがって、dropDuplicatesメソッドを使用する際は、バッククオート(``)を含まないカラム名を引数として与えてください。

image.png

エラーの再現方法

事前準備

検証用のデータフレームを作成

schema = """
`名前` string,
`数値` int
"""
data = [
    {
        "名前": "あ",
        "数値": 1,
    },
    {
        "名前": "い",
        "数値": 2,
    },
    {
        "名前": "う",
        "数値": 3,
    },
]

df = spark.createDataFrame(data, schema)

image.png

selectメソッドの動作確認

df.select(["`名前`", "`数値`"]).display()

image.png

エラーの再現

dropDuplicatesメソッドのエラー

col_list = ["`名前`"]
df.dropDuplicates(col_list).display()

AnalysisException: Cannot resolve column name "名前" among (名前, 数値).

image.png

joinメソッドのエラー

col_list = ["`名前`"]
df.join(df, col_list, "INNER").display()

AnalysisException: [UNRESOLVED_USING_COLUMN_FOR_JOIN] USING column 名前 cannot be resolved on the left side of the join. The left-side columns: [名前, 数値].

image.png

対応方法

dropDuplicatesメソッドのエラーへの対応方法

col_list = ["`名前`"]
trimed_col_list = [col.lstrip("`").rstrip("`") for col in col_list]
df.dropDuplicates(trimed_col_list).display()

image.png

joinメソッドのエラーへの対応方法

col_list = ["`名前`"]
trimed_col_list = [col.lstrip("`").rstrip("`") for col in col_list]
df.join(df, trimed_col_list, "INNER").display()

image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0