PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Accéder à des fichiers XML externes en tant que variables dans un script PSQL (provenant d'un script bash)

OK, voici ma solution.

Je poste une réponse plus détaillée sur mon blog Persagen.com.

Fondamentalement, j'ai décidé d'abroger le DO $$DECLARE ... approche (décrite dans SO 49950384) en faveur de l'approche simplifiée, ci-dessous.

Je peux alors accéder à la variable partagée BASH / PSQL, :bash_var , ainsi :

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

Voici un exemple de script SQL illustrant cette utilisation :

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;

Remarques sur les scripts SQL :

  • Dans les instructions xpath, j'ai refondu le ::text (ex :::text::varchar(15) ) selon le schéma de table Postgres.

  • Plus important encore, si je ne le faisais pas refondre les types de données dans l'instruction xpath et une entrée de champ (par exemple, name longueur) a dépassé le SQL varchar(300) limite de longueur, ces données ont généré une erreur PSQL et la table n'a pas été mise à jour (c'est-à-dire qu'une table vide en résulte).

J'ai téléchargé les fichiers de données XML utilisés dans cette réponse à ce Gist

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

Liens directs :

  • hmdb_metabolites_5000-01.xml

  • hmdb_metabolites_5000-02.xml

  • hmdb_metabolites_5000-03.xml

  • Source :HMDB.ca

    • Citation

MISE À JOUR (2019-05-15)

Dans un travail de suivi, détaillé dans mon article de blog de recherche Exportation de texte brut vers PostgreSQL, je charge directement les données XML dans PostgreSQL, plutôt que d'utiliser des tables temporaires.

TL/DR. Dans ce projet, j'ai observé les améliorations suivantes.

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