【问题标题】:"INSERT INTO ..." with SparkSQL HiveContext“插入...”与 SparkSQL HiveContext
【发布时间】:2016-02-28 15:31:23
【问题描述】:

我正在尝试使用我的 HiveContext 运行插入语句,如下所示:

hiveContext.sql('insert into my_table (id, score) values (1, 10)')

1.5.2 Spark SQL Documentation 没有明确说明是否支持此功能,尽管它确实支持“动态分区插入”。

这会导致类似的堆栈跟踪

AnalysisException: 
Unsupported language features in query: insert into my_table (id, score) values (1, 10)
TOK_QUERY 0, 0,20, 0
  TOK_FROM 0, -1,20, 0
    TOK_VIRTUAL_TABLE 0, -1,20, 0
      TOK_VIRTUAL_TABREF 0, -1,-1, 0
        TOK_ANONYMOUS 0, -1,-1, 0
      TOK_VALUES_TABLE 1, 13,20, 41
        TOK_VALUE_ROW 1, 15,20, 41
          1 1, 16,16, 41
          10 1, 19,19, 44
  TOK_INSERT 1, 0,-1, 12
    TOK_INSERT_INTO 1, 0,11, 12
      TOK_TAB 1, 4,4, 12
        TOK_TABNAME 1, 4,4, 12
          my_table 1, 4,4, 12
      TOK_TABCOLNAME 1, 7,10, 22
        id 1, 7,7, 22
        score 1, 10,10, 26
    TOK_SELECT 0, -1,-1, 0
      TOK_SELEXPR 0, -1,-1, 0
        TOK_ALLCOLREF 0, -1,-1, 0

scala.NotImplementedError: No parse rules for:
 TOK_VIRTUAL_TABLE 0, -1,20, 0
  TOK_VIRTUAL_TABREF 0, -1,-1, 0
    TOK_ANONYMOUS 0, -1,-1, 0
  TOK_VALUES_TABLE 1, 13,20, 41
    TOK_VALUE_ROW 1, 15,20, 41
      1 1, 16,16, 41
      10 1, 19,19, 44

有没有其他方法可以插入到支持的 Hive 表中?

【问题讨论】:

    标签: apache-spark apache-spark-sql pyspark apache-spark-1.5 hivecontext


    【解决方案1】:

    可以使用 DataFrameWriter 上的append 模式将数据附加到 Hive 表中。

    data = hc.sql("select 1 as id, 10 as score")
    data.write.mode("append").saveAsTable("my_table")
    

    这给出了与插入相同的结果。

    【讨论】:

    • 我想将其写入现有表。我怎样才能做到这一点?我使用的是 Spark 1.1.0,它没有 write 方法。在这种情况下我该怎么办?
    • 您愿意接受这个答案,以便我们关闭这个问题吗? :)
    • @eliasah 我已经在您指定的方法中进行了追加,但是当我在蜂巢表上执行 select * 时,我得到的附加行位于顶部,而不是位于底部
    • @Virureddy 我不确定你的问题是针对我的。
    • 这个答案在我的情况下不起作用。我收到一个错误:AnalysisException: 'Saving data in the Hive serde table `mytable` is not supported yet. Please use the insertInto() API as an alternative..;'
    【解决方案2】:

    我遇到了同样的问题(Spark 1.5.1),并尝试了不同的版本。

    给定

    sqlContext.sql("create table my_table(id int, score int)")
    

    唯一有效的版本如下所示:

    sqlContext.sql("insert into table my_table select t.* from (select 1, 10) t")
    sqlContext.sql("insert into       my_table select t.* from (select 2, 20) t")
    

    【讨论】:

    • 我们如何在查询中添加变量?
    • 如果您有一个与目标表具有相同键的源表,这也是一个可行的解决方案。在 spark 1.5 中工作
    • @yAsH 在 Pyspark 中使用字符串格式来使用变量,我的意思是上面的例子 sqlContext.sql("insert into my_table select t.* from (select 2, {variable}) t".format( variable = 20)) ### 这里可以代替 20 任何变量
    【解决方案3】:

    接受的答案saveAsTable 对我来说失败了AnalysisException(我不明白为什么)。对我有用的是:

    data = hc.sql("select 1 as id, 10 as score")
    data.write.mode("append").insertInto("my_table")
    

    我正在使用 Spark v2.1.0。

    【讨论】:

      【解决方案4】:

      您尝试执行数据文件格式无法执行的操作,因此出现Unsupported language features in query 异常。

      很多数据文件格式都是一次性写入的,不支持ACID操作。

      如果您需要,Apache ORC 支持 ACID 操作。

      相反,您可以使用分区将数据拆分为文件夹 (/data/year=2017/month=10....),在这里您可以将数据附加/插入到数据湖中。

      【讨论】:

        【解决方案5】:

        试试这个hiveContext.sql("insert into table my_table select 1, 10") 如果您还没有将动态分区模式更改为非严格模式,则必须这样做hiveCtx.setConf("hive.exec.dynamic.partition.mode", "nonstrict")

        【讨论】:

        • 为什么 OP 应该“试试这个代码”? 好的答案将始终解释所做的事情以及为什么以这种方式完成,不仅适用于 OP,而且适用于 SO 的未来访问者。
        • 此外,它不工作......见下面铍的回答,它工作
        【解决方案6】:

        当你第一次这样做时

        $data.write.mode("append").saveAsTable("my_table")
        

        您应该将"append"替换为"overwrite",然后,您可以使用"append"

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-03-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-03-20
          • 2018-02-18
          • 1970-01-01
          相关资源
          最近更新 更多