PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Importujesz schemat xml do postgres, aby automatycznie utworzyć tabelę, a następnie wypełnić ją plikiem xml?

Istnieje prawdopodobnie tysiąc sposobów importowania plików XML do PostgreSQL, ale tutaj jest alternatywa, którą uważam za dość łatwą do wdrożenia i jest już przetestowana z dużymi dokumentami xml (120 GB+)

W zależności od rozmiaru pliku XML rozważ podzielenie go. Świetnym narzędziem do tego jest xml_split . To polecenie dzieli file.xml w mniejszych plikach o maksymalnej wielkości 100 MB:

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

Po podzieleniu plików w rozsądnym rozmiarze możesz zacząć je importować bez ryzyka braku pamięci.

Rozważmy następującą strukturę pliku XML ...

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

... i następującą tabelę docelową, w której wstawimy rekordy XML.

CREATE TABLE t (id TEXT, entry XML);

Poniższy kod importuje pliki XML do tymczasowego niezalogowany tabela i unnest je do tabeli t przy użyciu CTE (aka klauzula WITH) przez węzeł <foo> . Polecenie perl -pe 's/\n/\\n/g' zastępuje znaki nowej linii na \\n dzięki czemu nie otrzymasz Premature end of data wyjątek:

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

A oto Twoje dane:

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Czy mogę uruchomić na sucho polecenia sql/sandbox?

  2. Jak debugować:Błąd wewnętrzny bieżąca transakcja jest przerwana, polecenia ignorowane do końca bloku transakcji

  3. Zakleszczenia w PostgreSQL podczas uruchamiania UPDATE

  4. Uzyskaj pierwszą datę miesiąca w postgres

  5. Docker — Jak uruchomić polecenie psql w kontenerze postgres?