【问题标题】:How do I output the results of a HiveQL query to CSV?如何将 HiveQL 查询的结果输出到 CSV?
【发布时间】:2013-08-10 09:01:11
【问题描述】:

我们希望将 Hive 查询的结果放入 CSV 文件。我认为命令应该是这样的:

insert overwrite directory '/home/output.csv' select books from table;

当我运行它时,它说它已成功完成,但我永远找不到该文件。我如何找到这个文件,或者我应该以不同的方式提取数据?

【问题讨论】:

    标签: database hadoop hive hiveql


    【解决方案1】:

    虽然可以使用INSERT OVERWRITE 从 Hive 中获取数据,但对于您的特定情况,这可能不是最佳方法。我先解释一下INSERT OVERWRITE 做了什么,然后我会描述我用来从 Hive 表中获取 tsv 文件的方法。

    根据the manual,您的查询会将数据存储在 HDFS 的目录中。格式不会是 csv。

    写入文件系统的数据被序列化为文本,列由 ^A 分隔,行由换行符分隔。如果任何列不是原始类型,则将这些列序列化为 JSON 格式。

    稍作修改(添加LOCAL 关键字)会将数据存储在本地目录中。

    INSERT OVERWRITE LOCAL DIRECTORY '/home/lvermeer/temp' select books from table;
    

    当我运行类似的查询时,输出如下所示。

    [lvermeer@hadoop temp]$ ll
    total 4
    -rwxr-xr-x 1 lvermeer users 811 Aug  9 09:21 000000_0
    [lvermeer@hadoop temp]$ head 000000_0 
    "row1""col1"1234"col3"1234FALSE
    "row2""col1"5678"col3"5678TRUE
    

    就个人而言,我通常在命令行上直接通过 Hive 运行查询,然后将其通过管道传输到本地文件中,如下所示:

    hive -e 'select books from table' > /home/lvermeer/temp.tsv
    

    这给了我一个可以使用的制表符分隔文件。希望对你也有用。

    基于this patch-3682,我怀疑使用 Hive 0.11 时会有更好的解决方案,但我无法自己测试。新语法应允许以下内容。

    INSERT OVERWRITE LOCAL DIRECTORY '/home/lvermeer/temp' 
    ROW FORMAT DELIMITED 
    FIELDS TERMINATED BY ',' 
    select books from table;
    

    希望对您有所帮助。

    【讨论】:

    • 你知道插入覆盖本地和管道之间的任何性能差异吗?在多大的近似体积下它可能会成为一个问题,而且,管道保证你会得到一个文件,因为另一种方法给我们一个目录之后我们可能需要合并
    • 能否将HDFS中的数据导出为Sequence文件格式?
    • 我尝试了解决方案 (patch-3682),它对我来说效果很好 - 除了由于某种原因输出文件不包含标题。请注意,我已设置 hive.cli.print.header=true;在我的 .hiverc 中。值得将标题打印到终端而不是(这显然不是我想要的)。
    • @lukas-vermeer,当您使用“INSERT OVERWRITE”方法创建表时,表头信息会丢失。有没有办法获取头信息?
    • 嗨 Lukas,你是如何让你的 shell 在 hadoop 文件系统中工作的?
    【解决方案2】:

    如果你想要一个 CSV 文件,那么你可以修改 Lukas 的解决方案如下(假设你在一个 linux 机器上):

    hive -e 'select books from table' | sed 's/[[:space:]]\+/,/g' > /home/lvermeer/temp.csv
    

    【讨论】:

    • 谢谢。我正在使用一种变体,但效果很好。请注意,这将输出逗号分隔,不一定是某些人认为的 CSV。 CSV 通常有一些格式来处理带有逗号的数据(例如,用双引号包裹数据,用双引号包裹数据)。值得一提的是,添加“--hiveconf hive.cli.print.header=True”参数也会在输出中获取标题。
    • 这是最干净的解决方案
    • 这对我来说失败了,例如,日期和时间之间有空格的日期时间字符串。
    • @williaster sed 's/\t\+/,/g' 这应该有助于解决这个问题。
    • 如果 tsv 有包含逗号的文本,这将不起作用。 (因为不带引号的无辜字符串逗号将被视为分隔符)
    【解决方案3】:

    这是我发现输出 HiveQL 结果的最 csv 友好的方式。
    您不需要任何 grep 或 sed 命令来格式化数据,而是 hive 支持它,只需要添加额外的 outputformat 标记。

    hive --outputformat=csv2 -e 'select * from <table_name> limit 20' > /path/toStore/data/results.csv
    

    【讨论】:

      【解决方案4】:

      您应该使用 CREATE TABLE AS SELECT (CTAS) 语句在 HDFS 中创建一个目录,其中包含包含查询结果的文件。之后,您必须将这些文件从 HDFS 导出到您的常规磁盘并将它们合并到一个文件中。

      您可能还需要做一些技巧来将文件从 '\001' - 分隔为 CSV。您可以使用自定义 CSV SerDe 或对提取的文件进行后处理。

      【讨论】:

      • 如果想在后续的 oozie 管道步骤中使用输出,这种方法是最好的。
      【解决方案5】:

      您可以使用INSERT ... DIRECTORY ...,如下例所示:

      INSERT OVERWRITE LOCAL DIRECTORY '/tmp/ca_employees'
      SELECT name, salary, address
      FROM employees
      WHERE se.state = 'CA';
      

      OVERWRITELOCAL 具有与以前相同的解释,并且路径按照通常的规则进行解释。一个或多个文件将写入/tmp/ca_employees,具体取决于调用的reducer 的数量。

      【讨论】:

        【解决方案6】:

        如果您使用 HUE,这也相当简单。只需转到 HUE 中的 Hive 编辑器,执行您的 Hive 查询,然后在本地将结果文件保存为 XLS 或 CSV,或者您可以将结果文件保存到 HDFS。

        【讨论】:

          【解决方案7】:

          我一直在寻找类似的解决方案,但这里提到的那些都行不通。我的数据有各种空格(空格、换行符、制表符)字符和逗号。

          为了使列数据tsv安全,我将列数据中的所有\t字符替换为空格,并在命令行执行python代码生成csv文件,如下图:

          hive -e 'tab_replaced_hql_query' |  python -c 'exec("import sys;import csv;reader = csv.reader(sys.stdin, dialect=csv.excel_tab);writer = csv.writer(sys.stdout, dialect=csv.excel)\nfor row in reader: writer.writerow(row)")'
          

          这创建了一个完全有效的 csv。希望这对那些寻求此解决方案的人有所帮助。

          【讨论】:

          • 现在是 2016 年,我们仍然需要跳过铁环才能做到这一点?我发现 shravster 的解决方案是迄今为止最好、最优雅的解决方案。
          • 如何替换列 data 中的所有 \t 字符?您是在查询中解决它还是为它创建了一个单独的视图?
          • @NareshS,抱歉回复晚了。是的,这些列是在 hive 中处理的,以用空格替换制表符,或者如果它们是必不可少的,您可以用 <:tab> 之类的替代品替换,或者类似的东西
          • @sisanared,感谢您的回复。我看到我们需要对所有字符串列使用正则表达式替换,如果我们有一个包含大量列 > 100 的表,这将很麻烦。这种情况有没有快速解决方案
          • @NareshS,不幸的是,唯一的其他解决方案是在将数据放入分区之前清理数据。否则,您必须在对所有可能包含制表符的字符串列执行选择时这样做
          【解决方案8】:

          可以使用hive字符串函数CONCAT_WS( string delimiter, string str1, string str2...strn )

          例如:

          hive -e 'select CONCAT_WS(',',cola,colb,colc...,coln) from Mytable' > /home/user/Mycsv.csv
          

          【讨论】:

            【解决方案9】:

            我遇到了类似的问题,这就是我能够解决的方法。

            第 1 步 - 将 Hive 表中的数据加载到另一个表中,如下所示

            DROP TABLE IF EXISTS TestHiveTableCSV;
            CREATE TABLE TestHiveTableCSV 
            ROW FORMAT DELIMITED 
            FIELDS TERMINATED BY ','
            LINES TERMINATED BY '\n' AS
            SELECT Column List FROM TestHiveTable;
            

            第 2 步 - 将 Blob 从 Hive 仓库复制到具有适当扩展名的新位置

            Start-AzureStorageBlobCopy
            -DestContext $destContext 
            -SrcContainer "Source Container"
            -SrcBlob "hive/warehouse/TestHiveTableCSV/000000_0"
            -DestContainer "Destination Container"
            -DestBlob "CSV/TestHiveTable.csv"
            

            【讨论】:

              【解决方案10】:
              hive  --outputformat=csv2 -e "select * from yourtable" > my_file.csv
              

              hive  --outputformat=csv2 -e "select * from yourtable" > [your_path]/file_name.csv
              

              对于 tsv,只需在上述查询中将 csv 更改为 tsv 并运行您的查询

              【讨论】:

                【解决方案11】:

                默认分隔符是“^A”。在python语言中是“\x01”。

                当我想更改分隔符时,我使用 SQL 如下:

                SELECT col1, delimiter, col2, delimiter, col3, ..., FROM table
                

                然后,将 delimiter+"^A" 视为新的分隔符。

                【讨论】:

                  【解决方案12】:

                  我尝试了各种选项,但这将是Python Pandas 最简单的解决方案之一:

                  hive -e 'select books from table' | grep "|" ' > temp.csv
                  
                  df=pd.read_csv("temp.csv",sep='|')
                  

                  您也可以使用tr "|" "," 转换“|”到“,”

                  【讨论】:

                    【解决方案13】:

                    与上面 Ray 的回答类似,Hortonworks Data Platform 中的 Hive View 2.0 也允许您运行 Hive 查询,然后将输出保存为 csv。

                    【讨论】:

                      【解决方案14】:

                      如果您是从 Windows 执行此操作,您可以使用 Python 脚本 hivehoney 将表数据提取到本地 CSV 文件。

                      它会:

                      1. 登录堡垒主机。
                      2. pbrun。
                      3. 启动。
                      4. 直线(与您的查询)。
                      5. 将直线回波保存到 Windows 上的文件中。

                      这样执行:

                      set PROXY_HOST=your_bastion_host
                      
                      set SERVICE_USER=you_func_user
                      
                      set LINUX_USER=your_SOID
                      
                      set LINUX_PWD=your_pwd
                      
                      python hh.py --query_file=query.sql
                      

                      【讨论】:

                        【解决方案15】:

                        只是为了在开始查询后涵盖更多以下步骤: INSERT OVERWRITE LOCAL DIRECTORY '/home/lvermeer/temp' ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' select books from table;

                        在我的例子中,temp文件夹下生成的数据是deflate格式, 它看起来像这样:

                        $ ls
                        000000_0.deflate  
                        000001_0.deflate  
                        000002_0.deflate  
                        000003_0.deflate  
                        000004_0.deflate  
                        000005_0.deflate  
                        000006_0.deflate  
                        000007_0.deflate
                        

                        以下是解压压缩文件并将所有内容放入一个 csv 文件的命令:

                        hadoop fs -text "file:///home/lvermeer/temp/*" > /home/lvermeer/result.csv
                        

                        【讨论】:

                          【解决方案16】:

                          我可能会迟到,但会帮助回答:

                          回显“COL_NAME1|COL_NAME2|COL_NAME3|COL_NAME4”> SAMPLE_Data.csv 蜂巢-e' 选择不同的连接(COL_1,“|”, COL_2, "|", COL_3, "|", COL_4) 如果需要,来自 table_Name where 子句;' >> SAMPLE_Data.csv

                          【讨论】:

                            【解决方案17】:

                            此 shell 命令将 csv 中的输出格式打印到 output.txt,不带列标题。

                            $ hive --outputformat=csv2 -f 'hivedatascript.hql' --hiveconf hive.cli.print.header=false > output.txt
                            

                            【讨论】:

                              【解决方案18】:

                              使用命令:

                              hive -e "use [database_name]; select * from [table_name] LIMIT 10;" > /path/to/file/my_file_name.csv

                              我有一个huge dataset,我试图组织并确定攻击类型和每种类型的数量。我在实践中使用的一个有效的例子(并且有更多细节)是这样的:

                              hive -e "use DataAnalysis;
                              select attack_cat, 
                              case when attack_cat == 'Backdoor' then 'Backdoors' 
                              when length(attack_cat) == 0 then 'Normal' 
                              when attack_cat == 'Backdoors' then 'Backdoors' 
                              when attack_cat == 'Fuzzers' then 'Fuzzers' 
                              when attack_cat == 'Generic' then 'Generic' 
                              when attack_cat == 'Reconnaissance' then 'Reconnaissance' 
                              when attack_cat == 'Shellcode' then 'Shellcode' 
                              when attack_cat == 'Worms' then 'Worms' 
                              when attack_cat == 'Analysis' then 'Analysis' 
                              when attack_cat == 'DoS' then 'DoS' 
                              when attack_cat == 'Exploits' then 'Exploits' 
                              when trim(attack_cat) == 'Fuzzers' then 'Fuzzers' 
                              when trim(attack_cat) == 'Shellcode' then 'Shellcode' 
                              when trim(attack_cat) == 'Reconnaissance' then 'Reconnaissance' end,
                              count(*) from actualattacks group by attack_cat;">/root/data/output/results2.csv
                              

                              【讨论】:

                                猜你喜欢
                                • 2019-05-14
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 2010-09-26
                                相关资源
                                最近更新 更多