sql >> Databasteknik >  >> RDS >> PostgreSQL

Importera ett xml-schema till postgres för att automatiskt skapa en tabell och sedan fylla i den med en xml-fil?

Det finns säkert tusen sätt att importera XML-filer till PostgreSQL, men här är ett alternativ som jag tycker är ganska enkelt att implementera och som redan är testat med stora xml-dokument (120GB+)

Beroende på storleken på din XML-fil, överväg att dela upp den. Ett fantastiskt verktyg för att göra det är xml_split . Detta kommando delar upp file.xml i mindre filer med maximalt 100MB:

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

När du har delat upp dina filer i en rimlig storlek kan du börja importera dem utan att riskera att ta slut på minne.

Låt oss överväga följande XML-filstruktur ...

<?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>

... och följande måltabell, där vi kommer att infoga XML-posterna.

CREATE TABLE t (id TEXT, entry XML);

Koden nedan importerar XML-filer till en tillfällig avloggad tabell och unnest dem i tabellen t med en CTE (aka WITH-sats) av noden <foo> . Kommandot perl -pe 's/\n/\\n/g' ersätter nyradstecken med \\n så att du inte får ett Premature end of data undantag:

#!/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;"

Och här är dina uppgifter:

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. använd en variabel för tabellnamn i mysql sproc

  2. XPath-fråga i hierarkisk data, bevarar relationen mellan anor och ättlingar

  3. Hur uppdaterar man fält för att lägga till värde till befintligt värde?

  4. Hur genererar jag kapslade json-objekt med inbyggda mysql-json-funktioner?