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 个不同的表,我打算这样做:
- 根据根元素划分XML文件
- 以不同的方式解析每种类型
- 加载到 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 索引。
我有一个 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 个不同的表,我打算这样做:
- 根据根元素划分XML文件
- 以不同的方式解析每种类型
- 加载到 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 索引。