解析大型XML并生成Hive表的最有效方法是什么?

时间:2018-12-29 17:20:26

标签: python hive

我正在尝试解析科学家产生的一个非常大的XML文件,生成将从该XML中提取的一组字段值,将结果存储在S3中,然后根据这些字段值创建一个Hive表

XML非常大-大约有1亿行,大约有300万行文本。但是格式是可以预测的,看起来像这样:

<Butterfly>
    <Name>Swallowtail&</Name>
    <HomePage>https://example.com/butterflies/swallowtail/</HomePage>
    <TaxonomyID>54321</TaxonomyID>
    <Grouping>Papilionidae</Grouping>
</Butterfly>

因此,假设每只蝴蝶都是一行,而每个孩子都是我表中的一个字段。我使用Python生成字段值,并用'\ t'分隔它们。使用xml.etree.ElementTree我从上到下解析每一行,使用类似以下的方法去除数据中的空格和制表符:     text_value = re.sub('\ s +','',field.text).rstrip()

然后,我将较大的字段值字符串转储到s3,最后一步是:

CREATE EXTERNAL TABLE IF NOT EXISTS butterflies (
Name STRING,
HomePage STRING,
TaxonomyID BIGINT,
Grouping STRING,
ROW FORMAT DELIMITED
FIELDS TERMINATED BY "\t"
STORED AS TEXTFILE
LOCATION 's3://butterflies/test_parsed_xml/';

Python步骤非常低效,并且需要到永远。 got 是一种更聪明的方法!有小费吗?另外,数据库没有逻辑分区。

我尝试使用python生成一个较大的字段值字符串,并将其推送到s3。有没有更智能的SerDe或更好的方法来做到这一点?

    field_values = ''
    row_count = 0
    for row in self.root_node:
        field_count = 0
        for field in row:
            if field.tag in self.schema[field_count]:
                if field.text:
                    text_value = re.sub('\s+', ' ', field.text).rstrip()
                else:
                    text_value = u''
                field_values = (field_values + text_value + '\t')
                field_count += 1
            else:
                raise ValueError()

        field_values = field_values + '\n'
        row_count += 1
        print("Processed row number {}".format(row_count))
    # Finally, code which pushes the huge string to s3

1 个答案:

答案 0 :(得分:0)

是的,有一种简单的方法可以使用,有第三方serde可以解析xml文件并将其作为配置单元表存储在hdfs中。

  

问题是,您的xml文件不是有效的xml文件。您需要删除&并确保所有标签均已关闭。即HomePage

参考:

https://github.com/dvasilen/Hive-XML-SerDe/wiki/XML-data-sources

  • 从那里下载最新的jar。 https://search.maven.org/search?q=hivexmlserde
  • 将罐子移到您的HDFS目录hdfs dfs -put hivexmlserde-1.0.5.3.jar
  • 加载jar文件add jar hivexmlserde-1.0.5.3.jar
  • 确保使用list jars;加载jar。

如果您能够看到jar,则说明您已正确完成操作,否则错过了某些内容。

现在,使用上面提到的serde创建表,如下所述。

CREATE EXTERNAL TABLE IF NOT EXISTS butterflies (
Name STRING,
HomePage STRING,
TaxonomyID BIGINT,
`Grouping` STRING)
ROW FORMAT SERDE 'com.ibm.spss.hive.serde2.xml.XmlSerDe'
WITH SERDEPROPERTIES (
"column.xpath.Name"="/Butterfly/Name/text()",
"column.xpath.HomePage"="/Butterfly/HomePage/text()",
"column.xpath.TaxonomyID"="/Butterfly/TaxonomyID/text()",
"column.xpath.Grouping"="/Butterfly/Grouping/text()"
)

STORED AS
INPUTFORMAT 'com.ibm.spss.hive.serde2.xml.XmlInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.IgnoreKeyTextOutputFormat'

location '/tmp/test_xml/table/'
TBLPROPERTIES (
"xmlinput.start"="<Butterfly",
"xmlinput.end"="</Butterfly>"
);

此后,将xml文件移动到/tmp/test_xml/table/位置。