指定列的 Spark sql 问题

Posted

技术标签:

【中文标题】指定列的 Spark sql 问题【英文标题】:Spark sql issue with columns specified 【发布时间】:2018-12-17 09:49:44 【问题描述】:

我们正在尝试将一个 oracle 数据库复制到 hive 中。我们从 oracle 获取查询并在 hive 中运行它们。 因此,我们以这种格式获取它们:

INSERT INTO schema.table(col1,col2) VALUES ('val','val');

虽然此查询直接在 Hive 中工作,但当我使用 spark.sql 时,我收到以下错误:

org.apache.spark.sql.catalyst.parser.ParseException:
mismatched input 'emp_id' expecting '(', 'SELECT', 'FROM', 'VALUES', 'TABLE', 'INSERT', 'MAP', 'REDUCE'(line 1, pos 20)
== SQL ==
insert into ss.tab(emp_id,firstname,lastname) values ('1','demo','demo')
--------------------^^^
        at org.apache.spark.sql.catalyst.parser.ParseException.withCommand(ParseDriver.scala:217)
        at org.apache.spark.sql.catalyst.parser.AbstractSqlParser.parse(ParseDriver.scala:114)
        at org.apache.spark.sql.execution.SparkSqlParser.parse(SparkSqlParser.scala:48)
        at org.apache.spark.sql.catalyst.parser.AbstractSqlParser.parsePlan(ParseDriver.scala:68)
        at org.apache.spark.sql.SparkSession.sql(SparkSession.scala:623)
        at org.apache.spark.sql.SQLContext.sql(SQLContext.scala:691)
        at com.datastream.SparkReplicator.insertIntoHive(SparkReplicator.java:20)
        at com.datastream.App.main(App.java:67)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:755)
        at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:180)
        at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:205)
        at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:119)
        at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)

【问题讨论】:

此外,该命令与 spark.sql(insert into ss.tab(val1,val2) 直接一起使用。有什么解决方案吗?或者是一种剥离 (col1,col2) 查询的方法? 【参考方案1】:

由于 Spark SQL 不支持插入语句中的列列表,因此出现此错误。所以从插入语句中排除列列表。

下面是我的蜂巢表:

select * from UDB.emp_details_table;
+---------+-----------+-----------+-------------------+--+
| emp_id  | emp_name  | emp_dept  | emp_joining_date  |
+---------+-----------+-----------+-------------------+--+
| 1       | AAA       | HR        | 2018-12-06        |
| 1       | BBB       | HR        | 2017-10-26        |
| 2       | XXX       | ADMIN     | 2018-10-22        |
| 2       | YYY       | ADMIN     | 2015-10-19        |
| 2       | ZZZ       | IT        | 2018-05-14        |
| 3       | GGG       | HR        | 2018-06-30        |
+---------+-----------+-----------+-------------------+--+

这里我通过 pyspark 使用 spark sql 插入记录

df = spark.sql("""insert into UDB.emp_details_table values ('6','VVV','IT','2018-12-18')""");

您可以在下面看到给定的记录已插入到我现有的配置单元表中。

+---------+-----------+-----------+-------------------+--+
| emp_id  | emp_name  | emp_dept  | emp_joining_date  |
+---------+-----------+-----------+-------------------+--+
| 1       | AAA       | HR        | 2018-12-06        |
| 1       | BBB       | HR        | 2017-10-26        |
| 2       | XXX       | ADMIN     | 2018-10-22        |
| 2       | YYY       | ADMIN     | 2015-10-19        |
| 2       | ZZZ       | IT        | 2018-05-14        |
| 3       | GGG       | HR        | 2018-06-30        |
| 6       | VVV       | IT        | 2018-12-18        |
+---------+-----------+-----------+-------------------+--+

将您的 spark sql 查询更改为:

spark.sql("""insert into ss.tab values ('1','demo','demo')""");

注意:我使用的是 spark 2.3,您需要使用 hive 上下文以防万一 正在使用 spark 1.6 版本。

让我知道它是否有效。

【讨论】:

是的,我遵循了类似的路径。自从我在运行时收到查询以来,我使用一些字符串操作剥离了列,无论如何,谢谢。

以上是关于指定列的 Spark sql 问题的主要内容,如果未能解决你的问题,请参考以下文章

在 Spark SQL 中查找多个双数据类型列的中位数

如何在 Spark SQL 中获取列的数据类型?

如何提高具有数组列的 DataFrame 的 Spark SQL 查询性能?

如何在 Spark SQL 中找到分组向量列的平均值?

Spark SQL - 转换为数据集列的 UUID 引发解析异常

如何计算列的每个值所在的百分位数? (Spark SQL)[重复]