XML 使用 python 到 postgres

XML to postgres using python

我有一个 XML 文件,其中包含来自美国互联网号码注册机构的数据,我需要使用这些数据来查找 CIDR 块。数据量在60GB左右。

结构不是那么复杂(可以映射到关系模型中的 4 个表)

<asn>
    <ref>https://whois.arin.net/rest/v1/asn/AS0</ref>
    <pocLinks/>
    <endAsNumber>0</endAsNumber>
    <handle>AS0</handle>
    <name>IANA-RSVD-0</name>
    <orgHandle>IANA</orgHandle>
    <comment>
        <line number="0">Reserved - May be used to identify non-routed networks</line>
    </comment>
    <registrationDate>2002-09-13T15:46:16-04:00</registrationDate>
    <startAsNumber>0</startAsNumber>
    <updateDate>2002-09-13T15:46:16-04:00</updateDate>
</asn>



<org>
    <ref>https://whois.arin.net/rest/v1/org/C07182099</ref>
    <city>BEVERLY HILLS</city>
    <iso3166-1>
        <code2>US</code2>
        <code3>USA</code3>
        <name>United States</name>
        <e164>1</e164>
    </iso3166-1>
    <handle>C07182099</handle>
    <customer>Y</customer>
    <name>NICHOLAS R. NIKOLOV</name>
    <pocLinks/>
    <parentOrgHandle>CC-3517</parentOrgHandle>
    <postalCode>90210</postalCode>
    <registrationDate>2018-10-26T03:59:46-04:00</registrationDate>
    <iso3166-2>CA</iso3166-2>
    <streetAddress>
        <line number="0">436 N BEDFORD DR</line>
    </streetAddress>
    <updateDate>2018-10-26T03:59:46.821-04:00</updateDate>
</org>



<net>
    <ref>https://whois.arin.net/rest/v1/net/NET-64-179-77-160-1</ref>
    <endAddress>64.179.77.167</endAddress>
    <handle>NET-64-179-77-160-1</handle>
    <name>CHOICE1SWIPP771609</name>
    <netBlocks>
        <netBlock>
            <cidrLenth>29</cidrLenth>
            <endAddress>064.179.077.167</endAddress>
            <type>S</type>
            <startAddress>064.179.077.160</startAddress>
        </netBlock>
    </netBlocks>
    <pocLinks/>
    <orgHandle>C00477198</orgHandle>
    <parentNetHandle>NET-64-179-0-0-1</parentNetHandle>
    <registrationDate>2003-02-24T12:20:58-05:00</registrationDate>
    <startAddress>64.179.77.160</startAddress>
    <updateDate>2003-02-24T12:20:58-05:00</updateDate>
    <version>4</version>
</net>  



<poc>
    <ref>https://whois.arin.net/rest/v1/poc/FLOYD11-ARIN</ref>
    <city>Alexandria</city>
    <companyName>Aireco8Alexandria</companyName>
    <iso3166-1>
        <code2>US</code2>
        <code3>USA</code3>
        <name>United States</name>
        <e164>1</e164>
    </iso3166-1>
    <handle>FLOYD11-ARIN</handle>
    <isRoleAccount>Y</isRoleAccount>
    <emails>
        <email>mfloyd@aireco.com</email>
    </emails>
    <lastName>Floyd</lastName>
    <phones>
        <phone>
            <number>
                <phoneNumber>+1-703-941-0660</phoneNumber>
                <phoneType>O</phoneType>
                <pocHandle>FLOYD11-ARIN</pocHandle>
            </number>
            <type>
                <description>Office</description>
                <code>O</code>
            </type>
        </phone>
    </phones>
    <postalCode>22312</postalCode>
    <registrationDate>2006-04-04T19:27:40-04:00</registrationDate>
    <iso3166-2>VA</iso3166-2>
    <streetAddress>
        <line number="0">5712-F Gen Washington Dr</line>
    </streetAddress>
    <updateDate>2006-04-04T19:27:40-04:00</updateDate>
</poc>

有4种不同类型的根元素,即- POC 、 asn 、 org 和 net ,每种类型都有多个数据点

需要将数据推送到 RDS Postgres 实例中的 4 个不同的表,我打算这样做:

  1. 根据根元素划分XML文件
  2. 以不同的方式解析每种类型
  3. 加载到 df 并执行 df.to_sql

有没有更快的方法来实现这个?

一个潜在的解决方案。

Postgres 有一个处理非结构化数据的 jsonb 存储。您可以通过 xmltodict.parse() 使用 xmltodict 模块并将 XML 转换为 python 字典。

然后您可以将其转换为 JSON 并转储到数据库中。
您可以通过两种方式查询 levels/depth:

SELECT data FROM table WHERE data->'asn'->>'name' = 'IANA-RSVD-0'
SELECT data FROM table WHERE data @> '{"asn":{"name":"IANA-RSVD-0"}}'

后一个查询将利用 JSONB_PATH_OPS 索引。

https://www.postgresql.org/docs/11/functions-json.html