我有一个XML文件,其中包含以下设置。
<?xml version="1.0" encoding="utf-8"?>
<SomeRoottag>
<row Id="47513849" PostTypeId="1" />
<row Id="4751323" PostTypeId="4" />
<row Id="475546" PostTypeId="1" />
<row Id="47597" PostTypeId="2" />
</SomeRoottag>
我解析文件并使用以下代码将其保存为Hive表。
df = sqlContext.read.format('xml').option("rowTag","SomeRoottag").load("/tmp/xmlfile.xml")
flat=df.withColumn("rows2",explode(df.row)).select("rows2.*")
flat.write.format("parquet").saveAsTable("xml_table")
使用我的测试数据(10mb)一切正常,但是当我加载大文件(&gt; 50G)时,它失败了。 似乎火花JVM试图加载整个文件失败,因为它只有20G大。
使用这样的文件的最佳方法是什么?
更新
如果我执行以下操作,则不会收到任何数据:
df = (sqlContext.read.format('xml').option("rowTag", "row").load("/tmp/someXML.xml"))
df.printSchema()
df.show()
输出:
root
++
||
++
++
答案 0 :(得分:1)
请勿将SomeRoottag
用作rowTag
。它指示Spark将整个文档用作单行。代替:
df = (sqlContext.read.format('xml')
.option("rowTag", "row")
.load("/tmp/xmlfile.xml"))
现在没有必要爆炸:
df.write.format("parquet").saveAsTable("xml_table")
修改强>:
考虑到您的编辑,您会受到已知错误的影响。请参阅Self-closing tags are not supported as top-level rows #92。看起来目前在解决这个方面没有任何进展,所以你可能不得不:
手动解析文件。如果元素始终是单行,则可以使用udf
轻松完成。
from pyspark.sql.functions import col, udf
from lxml import etree
@udf("struct<id: string, postTypeId: string>")
def parse(s):
try:
attrib = etree.fromstring(s).attrib
return attrib.get("Id"), attrib.get("PostTypeId")
except:
pass
(spark.read.text("/tmp/someXML.xml")
.where(col("value").rlike("^\\s*<row "))
.select(parse("value").alias("value"))
.select("value.*")
.show())
# +--------+----------+
# | id|postTypeId|
# +--------+----------+
# |47513849| 1|
# | 4751323| 4|
# | 475546| 1|
# | 47597| 2|
# +--------+----------+