Postgres:导入大型XML文件

3

我需要将大型XML文件导入到数据库中,然后将其转换为另一种格式。

目前我正在尝试使用Postgres完成此操作。

我已经使用以下方法将一个250 MB的文件导入到表中:

insert into test
(name, "element")
SELECT 
     (xpath('//title/text()', myTempTable.myXmlColumn))[1]::text AS name
     ,myTempTable.myXmlColumn as "element"
FROM unnest(
    xpath
    (    '//test'
        ,XMLPARSE(DOCUMENT convert_from(pg_read_binary_file('test.xml'), 'UTF8'))
    )
) AS myTempTable(myXmlColumn)
;

但是当处理大文件时(我尝试了一个大于1GB的文件),我得到了以下错误:
SQL 错误[22023]: 错误:请求的长度过长 错误: 请求的长度过大。 错误: 请求的长度过大。
我的目标是导入和转换大小约为50 GB的文件。
有任何建议/替代方案吗?
更新:
这个想法不是将1GB文件导入到一个字段中。上面的代码能够在我的机器上将我的250MB文件在3m 57s内加载并拆分成1773844行。 我认为这不错。 在导入文件后,我可以相对快速地转换数据,因为Postgres擅长此项工作。
有更好的建议吗?

考虑一种连接到Postgres并支持流式XML阅读器的替代语言。 - Evert
当然,我尝试使用C#来做这件事,并且它可以工作,但是遍历大型文件总是需要很长时间。我现在考虑拆分文件并使用上面的脚本。 - dknaack
你的代码唯一的限制是文件必须在数据库服务器上,这并不总是可行的方法。为了更灵活,最好使用从STDIN复制的COPY命令。 - Jim Jones
1个回答

1

你尝试过使用 \COPY + UNNEST 的这种组合吗?

可以使用中间表..

CREATE TABLE tmp_tb (tmp_xml XML);

使用 psql 执行导入操作...

cat huge.xml | psql db -c "\COPY tmp_tb (tmp_xml) FROM STDIN;"

一旦您加载了XML,就可以内部解析它..
INSERT INTO tb (test) 
SELECT UNNEST(XPATH('//test',tmp_xml)) FROM tmp_tb

不幸的是,如果您的XML源具有任何格式错误,此方法将无法正常工作。您将收到类似于“ERROR:invalid XML content; DETAIL:line 1:Premature end of data in tag x line 1”的错误信息。 - Ben Wilson
1
@BenWilson,如果XML文档无效,出现错误是可以的 :-D 也许你应该使用sed或者perl去除无效字符,例如 cat huge.xml | perl -pe 's/\\\n/\n/g' | psql db -c "COPY ...;" - Jim Jones

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接