Le fichier externe est le meilleur et typique des données en masse
Le terme «données en masse» est lié à «beaucoup de données», il est donc naturel d'utiliser des données brutes originales , sans avoir besoin de les transformer en SQL. Les fichiers de données brutes typiques pour "insertion en bloc" sont CSV et JSON formats .
Insert en vrac avec une certaine transformation
Dans les applications ETL et les processus d'ingestion, nous devons modifier les données avant de les insérer. La table temporaire consomme (beaucoup) d'espace disque et ce n'est pas le moyen le plus rapide de le faire. Le wrapper de données étrangères (FDW) PostgreSQL est le meilleur choix.
Exemple CSV . Supposons que tablename (x, y, z)
le SQL et un fichier CSV comme
fieldname1,fieldname2,fieldname3
etc,etc,etc
... million lines ...
Vous pouvez utiliser le SQL classique COPY
pour charger ( comme les données d'origine) dans tmp_tablename
, les insérer des données filtrées dans tablename
... Mais, pour éviter la consommation de disque, le mieux est d'ingérer directement par
INSERT INTO tablename (x, y, z)
SELECT f1(fieldname1), f2(fieldname2), f3(fieldname3) -- the transforms
FROM tmp_tablename_fdw
-- WHERE condictions
;
Vous devez préparer la base de données pour FDW, et à la place statique, tmp_tablename_fdw
vous pouvez utiliser une fonction qui la génère :
CREATE EXTENSION file_fdw;
CREATE SERVER import FOREIGN DATA WRAPPER file_fdw;
CREATE FOREIGN TABLE tmp_tablename_fdw(
...
) SERVER import OPTIONS ( filename '/tmp/pg_io/file.csv', format 'csv');
Exemple JSON . Un ensemble de deux fichiers, myRawData1.json
et Ranger_Policies2.json
peut être ingéré par:
INSERT INTO tablename (fname, metadata, content)
SELECT fname, meta, j -- do any data transformation here
FROM jsonb_read_files('myRawData%.json')
-- WHERE any_condiction_here
;
où la fonction jsonb_read_files () lit tous les fichiers d'un dossier, définis par un masque:
CREATE or replace FUNCTION jsonb_read_files(
p_flike text, p_fpath text DEFAULT '/tmp/pg_io/'
) RETURNS TABLE (fid int, fname text, fmeta jsonb, j jsonb) AS $f$
WITH t AS (
SELECT (row_number() OVER ())::int id,
f as fname,
p_fpath ||'/'|| f as f
FROM pg_ls_dir(p_fpath) t(f)
WHERE f like p_flike
) SELECT id, fname,
to_jsonb( pg_stat_file(f) ) || jsonb_build_object('fpath',p_fpath),
pg_read_file(f)::jsonb
FROM t
$f$ LANGUAGE SQL IMMUTABLE;
Manque de streaming gzip
La méthode la plus fréquente pour «l'ingestion de fichiers» (principalement dans le Big Data) est de conserver le fichier d'origine au format gzip et de le transférer avec un algorithme de streaming , tout ce qui peut fonctionner rapidement et sans consommation de disque dans les canaux Unix:
gunzip remote_or_local_file.csv.gz | convert_to_sql | psql
Donc, idéal (futur) est une option de serveur pour le formatage .csv.gz
.