sql >> Database >  >> RDS >> PostgreSQL

Een xml-schema importeren in postgres om automatisch een tabel te maken en deze vervolgens te vullen met een xml-bestand?

Er zijn waarschijnlijk duizend manieren om XML-bestanden in PostgreSQL te importeren, maar hier is een alternatief dat ik vrij gemakkelijk te implementeren vind en dat al is getest met grote xml-documenten (120 GB+)

Afhankelijk van de grootte van uw XML-bestand, kunt u overwegen het te splitsen. Een geweldige tool om dit te doen is xml_split . Deze opdracht splitst file.xml in kleinere bestanden van maximaal 100 MB:

xml_split -n 5 -l 1 -s 100MB file.xml

Zodra u uw bestanden op een redelijke grootte hebt gesplitst, kunt u ze importeren zonder het risico te lopen dat het geheugen vol raakt.

Laten we eens kijken naar de volgende XML-bestandsstructuur ...

<?xml version="1.0"?>
<t>
    <foo>
        <id j="a">1</id>
        <val>bar1</val>
    </foo>
    <foo>
        <id j="b">8</id>
        <val>bar1</val>
    </foo>
    <foo>
        <id j="c">5</id>
        <val>bar1</val>
    </foo>
    <foo>
        <id j="b">2</id>
    </foo>
</t>

... en de volgende doeltabel, waar we de XML-records zullen invoegen.

CREATE TABLE t (id TEXT, entry XML);

De onderstaande code importeert XML-bestanden in een tijdelijke niet ingelogd table en unnest ze in de tabel t met behulp van een CTE (ook bekend als WITH-clausule) door het knooppunt <foo> . Het commando perl -pe 's/\n/\\n/g' vervangt nieuweregeltekens door \\n zodat u geen Premature end of data . krijgt uitzondering:

#!/bin/bash

psql testdb -c "CREATE UNLOGGED TABLE tmp (entry xml);"

for f in /path/to/your/files/;do

    cat $f | perl -pe 's/\n/\\n/g' |psql testdb -c "COPY tmp FROM STDIN;"
    psql testdb -c "
    WITH j AS (
      SELECT UNNEST(XPATH('//t/foo',entry)) AS entry FROM tmp
    )
      INSERT INTO t 
      SELECT XPATH('//foo/id/text()',j.entry),j.entry FROM j;

      TRUNCATE TABLE tmp;"

done

psql testdb -c "DROP TABLE tmp;"

En hier zijn uw gegevens:

testdb=# SELECT * FROM t;
 id  |          entry           
-----+--------------------------
 {1} | <foo>                   +
     |         <id j="a">1</id>+
     |         <val>bar1</val> +
     |     </foo>
 {8} | <foo>                   +
     |         <id j="b">8</id>+
     |         <val>bar1</val> +
     |     </foo>
 {5} | <foo>                   +
     |         <id j="c">5</id>+
     |         <val>bar1</val> +
     |     </foo>
 {2} | <foo>                   +
     |         <id j="b">2</id>+
     |     </foo>
(4 Zeilen)



  1. Amazon DynamoDB - Tafels ontwerpen op basis van vriendschappen

  2. InstallAllOracleASPNETProviders werkt niet correct

  3. MySQL:de datums in een tussenvoorwaarde gebruiken voor de resultaten

  4. Hoe BigDecimal-waarde ontvangen van kafka-makelaar deserialiseren via het debezium CDC-mechanisme?