PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Accesso a file XML esterni come variabili in uno script PSQL (proveniente da uno script bash)

OK, ecco la mia soluzione.

Pubblico una risposta più dettagliata sul mio blog Persagen.com.

Fondamentalmente, ho deciso di abrogare il DO $$DECLARE ... approccio (descritto nella SO 49950384) a favore dell'approccio semplificato, di seguito.

Sono quindi in grado di accedere alla variabile condivisa BASH / PSQL, :bash_var , quindi:

xpath('//metabolite', XMLPARSE(DOCUMENT convert_from(pg_read_binary_file(:'bash_var'))))

Ecco uno script SQL di esempio, che illustra tale utilizzo:

hmdb.sql

\c hmdb

CREATE TABLE hmdb_identifiers (
  id SERIAL,
  accession VARCHAR(15) NOT NULL,
  name VARCHAR(300) NOT NULL,
  cas_number VARCHAR(12),
  pubchem_cid INT,
  PRIMARY KEY (id),
  UNIQUE (accession)
);

\echo '\n[hmdb.sql] bash_var:' :bash_var '\n'

-- UPDATE (2019-05-15): SEE MY COMMENTS BELOW RE: TEMP TABLE!
CREATE TEMP TABLE tmp_table AS 
SELECT 
  (xpath('//accession/text()', x))[1]::text::varchar(15) AS accession
  ,(xpath('//name/text()', x))[1]::text::varchar(300) AS name 
  ,(xpath('//cas_registry_number/text()', x))[1]::text::varchar(12) AS cas_number 
  ,(xpath('//pubchem_compound_id/text()', x))[1]::text::int AS pubchem_cid 
-- FROM unnest(xpath('//metabolite', XMLPARSE(DOCUMENT convert_from(pg_read_binary_file('hmdb/hmdb.xml'), 'UTF8')))) x
FROM unnest(xpath('//metabolite', XMLPARSE(DOCUMENT convert_from(pg_read_binary_file(:'bash_var'), 'UTF8')))) x
;

INSERT INTO hmdb_identifiers (accession, name, cas_number, pubchem_cid)
  SELECT lower(accession), lower(name), lower(cas_number), pubchem_cid FROM tmp_table;

DROP TABLE tmp_table;

Note sugli script SQL:

  • Nelle istruzioni xpath ho riformulato il ::text (es.:::text::varchar(15) ) secondo lo schema della tabella Postgres.

  • Più significativamente, se lo facessi non riformulare i tipi di dati nell'istruzione xpath e una voce di campo (ad es. name length) ha superato l'SQL varchar(300) limite di lunghezza, quei dati hanno generato un errore PSQL e la tabella non è stata aggiornata (ad es. risulta una tabella vuota).

Ho caricato i file di dati XML utilizzati in questa risposta in questo Gist

https://gist.github.com/victoriastuart/d1b1959bd31e4de5ed951ff4fe3c3184

Link diretti:

  • hmdb_metabolites_5000-01.xml

  • hmdb_metabolites_5000-02.xml

  • hmdb_metabolites_5000-03.xml

  • Fonte:HMDB.ca

    • Citazione

AGGIORNAMENTO (15-05-2019)

Nel lavoro successivo, dettagliato nel mio post sul blog di ricerca Exporting Plain Text to PostgreSQL, carico direttamente i dati XML in PostgreSQL, invece di usare le tabelle temporanee.

TL/DR. In quel progetto, ho osservato i seguenti miglioramenti.

Parameter | Temp Tables  | Direct Import | Reduction
    Time: | 1048 min     | 1.75 min      | 599x
   Space: | 252,000 MB   | 18 MB         | 14,000x