如何在每个文件中执行多个SQL查询的hql文件?

时间:2017-11-30 06:48:10

标签: scala hadoop apache-spark hive apache-spark-sql

我有hql文件,它有很多hive查询,我想用Spark SQL执行整个文件。

这就是我的尝试。

val sqlContext = new org.apache.spark.sql.hive.HiveContext(sc) 

通常,为了执行单个查询,我们这样做:

sqlContext.sql("SELECT * from table")

但是,当我们有数百个查询的hql文件时,我会这样做。

import scala.io.Source 

val filename = "/path/to/file/filename.hql"
for (line <- Source.fromFile(filename).getLines) {
    sqlContext.sql(line)
}

但是,我收到错误说:

NoViableAltException

这是文件的顶部。

DROP TABLE dat_app_12.12_app_htf;

CREATE EXTERNAL TABLE dat_app_12.12_app_htf(stc string,
  ftg string,
  product_type string,
  prod_number string,
  prod_ident_number string,
  prod_family string,
  frst_reg_date date, gth_name string,
  address string,
  tel string,
  maker_name string) ROW format serde 'org.apache.hadoop.hive.ql.io.orc.OrcSerde'
stored AS inputformat 'org.apache.hadoop.hive.ql.io.orc.OrcInputFormat'
outputformat 'org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat'
LOCATION
  'file_location';

当查询是如上所述的多行查询时,它不起作用。 但是,当我格式化查询并将所有行放入一行时,它可以工作。

CREATE EXTERNAL TABLE dat_app_12.12_app_htf(stc string, ftg string, product_type string, prod_number string, prod_ident_number string, prod_family string, frst_reg_date date, gth_name string, address string, tel string, maker_name string) ROW format serde 'org.apache.hadoop.hive.ql.io.orc.OrcSerde' stored AS inputformat 'org.apache.hadoop.hive.ql.io.orc.OrcInputFormat' outputformat 'org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat' LOCATION 'file_location';

但我有成千上万的这样的台词。什么是正确的方法。

任何人都可以帮助解决这个问题。

2 个答案:

答案 0 :(得分:2)

tl; dr 我认为这不可能。

Spark SQL使用AstBuilder作为基于ANTLR的SQL解析器,并且一次只接受一个SQL语句(有关所有支持的SQL查询的完整内容,请参阅SqlBase.g4)。

话虽如此,唯一的方法是在调用Spark SQL的sqlContext.sql之前自己解析多查询输入文件spark.sql(或者从Spark 2.0开始// one query that ends with semicolon DROP TABLE dat_app_12.12_app_htf; // another query that also ends with semicolon CREATE EXTERNAL TABLE dat_app_12.12_app_htf(stc string, ftg string, product_type string, prod_number string, prod_ident_number string, prod_family string, frst_reg_date date, gth_name string, address string, tel string, maker_name string) ROW format serde 'org.apache.hadoop.hive.ql.io.orc.OrcSerde' stored AS inputformat 'org.apache.hadoop.hive.ql.io.orc.OrcInputFormat' outputformat 'org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat' LOCATION 'file_location'; )。

你可以依赖空行作为分隔符,但这取决于输入文件的结构(并且它们可以很容易地使用分号)。

在您的特定情况下,我注意到结束标记实际上是分号。

for

如果这是一致的,您可以逐行解析文件(与;表达式一样)并读取直到找到Active Connections Proto Local Address Foreign Address State PID TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 4 TCP 10.140.126.48:80 10.140.126.139:57030 ESTABLISHED 4 TCP 10.140.126.48:80 10.140.126.181:57918 ESTABLISHED 4 TCP [::]:80 [::]:0 LISTENING 4 。多行SQL查询适用于Spark SQL,因此您应该有自己的解决方案。

我在一个项目中有一个类似的用例,并且只是放弃了尝试解析人们编写SQL的所有可能方式,然后再将其交给Spark。

答案 1 :(得分:1)

嘿你有没有尝试过这个命令

spark-sql –master yarn-client –conf spark.ui.port=port -i /hadoop/sbscript/hql_for_dml.hql