如何合并外部表的orc文件?

时间:2017-12-13 13:49:44

标签: hadoop hive hdfs orc

我正在尝试合并多个小型ORC文件。遇到了ALTER TABLE CONCATENATE命令,但这只适用于托管表。

当我尝试运行时,Hive给了我以下错误:

  

失败:SemanticException   org.apache.hadoop.hive.ql.parse.SemanticException:Concatenate / Merge   只能在托管表上执行

以下是表格参数:

Table Type:             EXTERNAL_TABLE
Table Parameters:
    COLUMN_STATS_ACCURATE   true
    EXTERNAL                TRUE
    numFiles                535
    numRows                 27051810
    orc.compress            SNAPPY
    rawDataSize             20192634094
    totalSize               304928695
    transient_lastDdlTime   1512126635

# Storage Information
SerDe Library:          org.apache.hadoop.hive.ql.io.orc.OrcSerde
InputFormat:            org.apache.hadoop.hive.ql.io.orc.OrcInputFormat
OutputFormat:           org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat
Compressed:             No
Num Buckets:            -1
Bucket Columns:         []
Sort Columns:           []
Storage Desc Params:
    serialization.format    1

2 个答案:

答案 0 :(得分:2)

我相信你的表是一个外部表,然后有两种方法:

  1. 您可以将其更改为托管表(ALTER TABLE <table> SET TBLPROPERTIES('EXTERNAL'='FALSE')并运行ALTER TABLE CONCATENATE。然后您可以将其转换回外部更改 它到TRUE
  2. 您可以使用CTAS创建托管表并插入数据。然后运行合并查询并将数据导回到外部表

答案 1 :(得分:0)

根据我之前对 this question 的回答,这里有一个 Python 小脚本,它使用 PyORC 将小 ORC 文件连接在一起。它根本不使用 Hive,因此只有当您可以直接访问文件并能够在文件上运行 Python 脚本时才能使用它,而托管主机中可能并非总是如此。

import pyorc
import argparse


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-o', '--output', type=argparse.FileType(mode='wb'))
    parser.add_argument('files', type=argparse.FileType(mode='rb'), nargs='+')
    args = parser.parse_args()

    schema = str(pyorc.Reader(args.files[0]).schema)

    with pyorc.Writer(args.output, schema) as writer:
        for i, f in enumerate(args.files):
            reader = pyorc.Reader(f)
            if str(reader.schema) != schema:
                raise RuntimeError(
                    "Inconsistent ORC schemas.\n"
                    "\tFirst file schema: {}\n"
                    "\tFile #{} schema: {}"
                    .format(schema, i, str(reader.schema))
                )
            for line in reader:
                writer.write(line)


if __name__ == '__main__':
    main()