如何在 Spark SQL 中用连字符转义列名
How to escape column names with hyphen in Spark SQL
我已经在 Spark 中导入了一个 json 文件并将其转换为 table 作为
myDF.registerTempTable("myDF")
然后我想 运行 SQL 查询结果 table
val newTable = sqlContext.sql("select column-1 from myDF")
但是,由于列名称中的连字符 column-1
,这给了我一个错误。我该如何解决这是 Spark SQL?
反引号 (`) 似乎有效,所以
val newTable = sqlContext.sql("select `column-1` from myDF")
至少在 Spark v1 中应该可以做到这一点。3.x。
我不能发表评论,因为我的重复次数少于 50 次
当您使用 struct.struct.field 引用 json 结构并且存在如下命名空间时:
ns2:struct.struct.field 反引号 (`) 不起作用。
jsonDF = sqlc.read.load('jsonMsgs', format="json")
jsonDF.registerTempTable("masterTable")
sqlc.select("select `sn2:AnyAddRq.AnyInfo.noInfo.someRef.myInfo.someData.Name` AS sn2_AnyAddRq_AnyInfo_noInfo_someRef_myInfo_someData_Name from masterTable").show()
pyspark.sql.utils.AnalysisException: 你"无法解析'sn2:AnyAddRq.AnyInfo.noInfo.someRef.myInfo.someData.Name
'
如果我删除 sn2: 字段,查询就会执行。
我也尝试过使用单引号 (')、反斜杠 (\) 和双引号 ("")
如果我在 sn2: 结构上注册另一个临时 table,它唯一的工作方式是,我可以像这样访问其中的字段
anotherDF = jsonDF.select("sn2:AnyAddRq.AnyInfo.noInfo.someRef.myInfo.someData")
anotherDF.registerTempTable("anotherDF")
sqlc.select("select Name from anotherDF").show()
昨天研究了一下,发现有一种方法可以像这样转义 (:) 和 (.):
只有包含(:)的字段需要用反引号转义
sqlc.select("select `sn2:AnyAddRq`.AnyInfo.noInfo.someRef.myInfo.someData.Name AS sn2_AnyAddRq_AnyInfo_noInfo_someRef_myInfo_someData_Name from masterTable").show()
这就是我所做的,在 Spark 3.x
中也有效。
我在程序的顶部(或某些 global scope
中)定义了函数 litCol()
:
litCols = lambda seq: ','.join(('`'+x+'`' for x in seq)) # Accepts any sequence of strings.
然后根据需要应用它来准备我的字面化 SELECT
列。这是一个例子:
>>> UNPROTECTED_COLS = ["RegionName", "StateName", "2012-01", "2012-02"]
>>> LITERALIZED_COLS = litCols(UNPROTECTED_COLS)
>>> print(LITERALIZED_COLS)
`RegionName`,`StateName`,`2012-01`,`2012-02`
此示例中有问题的 column names
是 YYYY-MM
列,Spark
将解析为表达式,导致 2011
和 2010
,分别。
我已经在 Spark 中导入了一个 json 文件并将其转换为 table 作为
myDF.registerTempTable("myDF")
然后我想 运行 SQL 查询结果 table
val newTable = sqlContext.sql("select column-1 from myDF")
但是,由于列名称中的连字符 column-1
,这给了我一个错误。我该如何解决这是 Spark SQL?
反引号 (`) 似乎有效,所以
val newTable = sqlContext.sql("select `column-1` from myDF")
至少在 Spark v1 中应该可以做到这一点。3.x。
我不能发表评论,因为我的重复次数少于 50 次
当您使用 struct.struct.field 引用 json 结构并且存在如下命名空间时:
ns2:struct.struct.field 反引号 (`) 不起作用。
jsonDF = sqlc.read.load('jsonMsgs', format="json")
jsonDF.registerTempTable("masterTable")
sqlc.select("select `sn2:AnyAddRq.AnyInfo.noInfo.someRef.myInfo.someData.Name` AS sn2_AnyAddRq_AnyInfo_noInfo_someRef_myInfo_someData_Name from masterTable").show()
pyspark.sql.utils.AnalysisException: 你"无法解析'sn2:AnyAddRq.AnyInfo.noInfo.someRef.myInfo.someData.Name
'
如果我删除 sn2: 字段,查询就会执行。
我也尝试过使用单引号 (')、反斜杠 (\) 和双引号 ("")
如果我在 sn2: 结构上注册另一个临时 table,它唯一的工作方式是,我可以像这样访问其中的字段
anotherDF = jsonDF.select("sn2:AnyAddRq.AnyInfo.noInfo.someRef.myInfo.someData")
anotherDF.registerTempTable("anotherDF")
sqlc.select("select Name from anotherDF").show()
昨天研究了一下,发现有一种方法可以像这样转义 (:) 和 (.):
只有包含(:)的字段需要用反引号转义
sqlc.select("select `sn2:AnyAddRq`.AnyInfo.noInfo.someRef.myInfo.someData.Name AS sn2_AnyAddRq_AnyInfo_noInfo_someRef_myInfo_someData_Name from masterTable").show()
这就是我所做的,在 Spark 3.x
中也有效。
我在程序的顶部(或某些 global scope
中)定义了函数 litCol()
:
litCols = lambda seq: ','.join(('`'+x+'`' for x in seq)) # Accepts any sequence of strings.
然后根据需要应用它来准备我的字面化 SELECT
列。这是一个例子:
>>> UNPROTECTED_COLS = ["RegionName", "StateName", "2012-01", "2012-02"]
>>> LITERALIZED_COLS = litCols(UNPROTECTED_COLS)
>>> print(LITERALIZED_COLS)
`RegionName`,`StateName`,`2012-01`,`2012-02`
此示例中有问题的 column names
是 YYYY-MM
列,Spark
将解析为表达式,导致 2011
和 2010
,分别。