Java中的Spark Dataframe SQL-如何转义单引号

时间:2018-07-17 04:25:06

标签: apache-spark-sql

我正在使用spark-core,spark-sql,Spark-hive 2.10(1.6.1),scala-reflect 2.11.2。我正在尝试过滤通过配置单元上下文创建的数据框...

df = hiveCtx.createDataFrame(someRDDRow,
                    someDF.schema());

我要过滤的一列中有多个单引号。我的过滤器查询将类似于

df = df.filter("not (someOtherColumn= 'someOtherValue' and comment= 'That's Dany's Reply'"));

在发生此过滤器的java类中,我尝试将String变量替换为例如commentValueToFilterOut,该变量包含

值“ That's Dany's Reply”
commentValueToFilterOut= commentValueToFilterOut.replaceAll("'","\\\\'");

但是将过滤器应用于数据框时,出现以下错误...

java.lang.RuntimeException: [1.103] failure: ``)'' expected but identifier
s found

    not (someOtherColumn= 'someOtherValue' and comment=  'That\'s Dany\'s Reply'' )
                                                                ^                                          
    scala.sys.package$.error(package.scala:27)
    org.apache.spark.sql.catalyst.SqlParser$.parseExpression(SqlParser.scala:49)
    org.apache.spark.sql.DataFrame.filter(DataFrame.scala:768) 

请告知...

1 个答案:

答案 0 :(得分:0)

我们实施了一种解决方法来克服此问题。

解决方法:

在数据框中创建一个新列,然后将实际列中的值(其中包含特殊字符,可能会引起问题(如单引号))复制到不包含任何特殊字符的新列中。

df = df.withColumn("comment_new", functions.regexp_replace(df.col("comment"),"'",""));

修剪条件中的特殊字符并应用过滤器。

commentToFilter = "That's Dany's Reply'"
commentToFilter = commentToFilter.replaceAll("'","");
df = df.filter("(someOtherColumn= 'someOtherValue' and comment_new= '"+commentToFilter+"')");

现在,过滤器已应用,您可以删除仅为过滤目的创建的新列,并将其恢复到原始数据框。

df = df.drop("comment_new");

如果您不想在数据框中创建新列,也可以用同一列中的“永不发生”字符串文字替换特殊字符,例如

df = df.withColumn("comment", functions.regexp_replace(df.col("comment"),"'","^^^^"));

并对要应用的字符串文字进行相同操作

    comment_new       commentToFilter = "That's Dany's Reply'"
    commentToFilter = commentToFilter.replaceAll("'","^^^^");
    df = df.filter("(someOtherColumn= 'someOtherValue' and comment_new= '"+commentToFilter+"')");

一旦过滤完成,通过反向应用字符串litteral来恢复实际值

df = df.withColumn("comment", functions.regexp_replace(df.col("comment"),"^^^^", "'"));

尽管它不能解决实际问题,但是有相同问题的人可以尝试解决此问题。

实际的解决方案可能是使用sqlContext(而不是hiveContext)和/或Dataset(而不是dataframe)和/或升级到spark hive 2.12。

辩论和回答专家

PS:多亏了我的领导KP