sql >> Databasteknik >  >> RDS >> PostgreSQL

Få åtkomst till externa XML-filer som variabler i ett PSQL-skript (från ett bash-skript)

OK, här är min lösning.

Jag lägger upp ett mer detaljerat svar på min Persagen.com-blogg.

I grund och botten bestämde jag mig för att upphäva DO $$DECLARE ... tillvägagångssätt (beskrivs i SO 49950384) till förmån för det förenklade tillvägagångssättet nedan.

Jag kan sedan komma åt den delade BASH / PSQL variabeln, :bash_var , alltså:

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

Här är ett exempel på ett SQL-skript som illustrerar denna användning:

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;

SQL-skriptanteckningar:

  • I xpath-satserna omarbetar jag ::text (t.ex.:::text::varchar(15) ) enligt Postgres-tabellschemat.

  • Mer påtagligt, om jag inte gjorde det omarbeta datatyperna i xpath-satsen och en fältpost (t.ex. name length) överskred SQL varchar(300) längdgräns, dessa data gav ett PSQL-fel och tabellen uppdaterades inte (dvs. en tom tabell resulterade).

Jag laddade upp XML-datafilerna som användes i det här svaret vid den här Gist

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

Direktlänkar:

  • hmdb_metabolites_5000-01.xml

  • hmdb_metabolites_5000-02.xml

  • hmdb_metabolites_5000-03.xml

  • Källa:HMDB.ca

    • Citat

UPPDATERING (2019-05-15)

I efterföljande arbete, som beskrivs i mitt forskningsblogginlägg Exportera vanlig text till PostgreSQL, laddar jag in XML-data direkt i PostgreSQL istället för att använda tillfälliga tabeller.

TL/DR. I det projektet observerade jag följande förbättringar.

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



  1. Escape SQL LIKE-värde för Postgres med psycopg2

  2. Prestanda för sekvenser och serier i Postgres-XL

  3. Transponera dynamiska kolumner till rader

  4. Vilket är snabbast COALESCE ELLER ISNULL?