Java 将大型xml文件加载到Snowflake中并按标记展开

Java 将大型xml文件加载到Snowflake中并按标记展开,java,xml,snowflake-cloud-data-platform,Java,Xml,Snowflake Cloud Data Platform,我有一些非常大的XML文件需要处理。我曾经使用Spark处理它们,但现在我正从SQLDW转移到Snowflake,所以我不能再使用Spark了。在Spark中,有一个概念是通过向Spark函数提供行标记来扁平化XML文件。假设我们有这个persons.xml文件: 通过在.option函数中提供spark行标记person,我们得到如下数据帧: val df = spark.read .format("com.databricks.spark.xml") .option(

我有一些非常大的XML文件需要处理。我曾经使用Spark处理它们,但现在我正从SQLDW转移到Snowflake,所以我不能再使用Spark了。在Spark中,有一个概念是通过向Spark函数提供行标记来扁平化XML文件。假设我们有这个persons.xml文件:

通过在.option函数中提供spark行标记person,我们得到如下数据帧:

val df = spark.read
      .format("com.databricks.spark.xml")
      .option("rowTag", "person")
      .load("persons.xml");
display(df);
_id addresses   dob_month   dob_year    firstname   gender  lastname    middlename  salary                          
1   {"address":[{"city":"NewJersy","state":"NJ","street":"123 ABC street"},{"city":"newark","state":"DE","street":"456 apple street"}]} 1   1980    James   M   Smith       {"_VALUE":10000,"_currency":"Euro"}
2   {"address":[{"city":"new york","state":"NY","street":"4512 main st"},{"city":"sandiago","state":"CA","street":"4367 orange st"}]}   6   1990    Michael M       Rose    {"_VALUE":10000,"_currency":"Dollor"}
这有点难读,所以这里有一个图片来帮助

不管怎样,我想知道如果可能的话,我怎样才能用雪花做到这一点?如果可能的话,我希望避免预处理xml文件

记住,这些文件很大。1Gb+。也不能保证文件的行标记在开头或接近开头,它可能在文件下面几百行。

给您一些建议:

加载时,使用STRIP_OUTER_ELEMENT=TRUE来消除PERSONS标记,并使每个PERSON对象位于其自己的行中。这简化了数据并允许您加载更大的文件

展平XML以查找所有路径。例如,选择* 从my_表a中,输入=>a.data,递归=>true b

将路径从展平符号转换为字段符号,并构建查询:

例如,假设移除了人员外部标签:

select 
  data:"@id"::number id,
  data:"$"[0]."$"::text first_name,
  data:"$"[1]."$"::text last_name
from my_table; 
其中数据是XML列

希望有帮助

更新-用于上述查询的示例XML:

create or replace table my_table as
select parse_xml($1) as data 
from values ('
    <person id="1">
        <firstname>James</firstname>
        <lastname>Smith</lastname>
        <middlename></middlename>
        <dob_year>1980</dob_year>
        <dob_month>1</dob_month>
        <gender>M</gender>
        <salary currency="Euro">10000</salary>
        <addresses>
            <address>
                <street>123 ABC street</street>
                <city>NewJersy</city>
                <state>NJ</state>    
            </address>
            <address>
                <street>456 apple street</street>
                <city>newark</city>
                <state>DE</state>    
            </address>    
        </addresses>    
    </person>'),('
    <person id="2">
        <firstname>Michael</firstname>
        <lastname></lastname>
        <middlename>Rose</middlename>
        <dob_year>1990</dob_year>
        <dob_month>6</dob_month>
        <gender>M</gender>
        <salary currency="Dollor">10000</salary>
        <addresses>
            <address>
                <street>4512 main st</street>
                <city>new york</city>
                <state>NY</state>    
            </address>
            <address>
                <street>4367 orange st</street>
                <city>sandiago</city>
                <state>CA</state>    
            </address>    
        </addresses>            
    </person>
');

你能再解释一下第二点吗?我不擅长雪花,肯定是刚开始。这些想法是连续的——也就是说它们是相互依赖的,还是相互独立的?当我从头开始加载新的XML数据时,我会按顺序执行这些步骤。如果您的数据已经加载,并且您已经了解了Snowflake的XML路径语法,那么您可以直接跳到3。好的,您能稍微解释一下第二个吗?不确定将xml展平会是什么样子,特别是当其特别复杂的EDI get SQL编译错误时:文件格式xml不支持按列匹配名称选项是的,我也知道-这是非常令人流泪的。编辑:如果有人能告诉我更多关于复制和匹配列名称的信息,如果这是一个有效的解决方案,我将不胜感激
create or replace table my_table as
select parse_xml($1) as data 
from values ('
    <person id="1">
        <firstname>James</firstname>
        <lastname>Smith</lastname>
        <middlename></middlename>
        <dob_year>1980</dob_year>
        <dob_month>1</dob_month>
        <gender>M</gender>
        <salary currency="Euro">10000</salary>
        <addresses>
            <address>
                <street>123 ABC street</street>
                <city>NewJersy</city>
                <state>NJ</state>    
            </address>
            <address>
                <street>456 apple street</street>
                <city>newark</city>
                <state>DE</state>    
            </address>    
        </addresses>    
    </person>'),('
    <person id="2">
        <firstname>Michael</firstname>
        <lastname></lastname>
        <middlename>Rose</middlename>
        <dob_year>1990</dob_year>
        <dob_month>6</dob_month>
        <gender>M</gender>
        <salary currency="Dollor">10000</salary>
        <addresses>
            <address>
                <street>4512 main st</street>
                <city>new york</city>
                <state>NY</state>    
            </address>
            <address>
                <street>4367 orange st</street>
                <city>sandiago</city>
                <state>CA</state>    
            </address>    
        </addresses>            
    </person>
');