((ceci est un WIKI que vous pouvez modifier et améliorer la réponse !))
Le fichier externe est le meilleur et le plus typique des données en vrac.
Le terme " données en vrac " est lié à " beaucoup de données ", il est donc naturel d'utiliser données brutes originales sans qu'il soit nécessaire de le transformer en SQL. Les fichiers de données brutes typiques pour l'"insertion en masse" sont les suivants CSV y JSON formats.
Insertion en vrac avec une certaine transformation
En ETL et les processus d'ingestion, nous devons modifier les données avant de les insérer. Les tables temporaires consomment (beaucoup) d'espace disque, et ce n'est pas le moyen le plus rapide de le faire. Le site Enveloppeur de données étrangères PostgreSQL (FDW) est le meilleur choix.
Exemple CSV . Supposons que le tablename (x, y, z)
sur SQL et un fichier CSV comme
fieldname1,fieldname2,fieldname3
etc,etc,etc
... million lines ...
Vous pouvez utiliser la méthode SQL classique COPY
à charger ( en l'état données originales) en tmp_tablename
ils insèrent les 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 au lieu de statiques tmp_tablename_fdw
vous pouvez utiliser une fonction qui le 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
y 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éfini 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;
Absence de streaming gzip
La méthode la plus fréquente pour "l'ingestion de fichiers" (principalement dans le domaine du Big Data) consiste à conserver le fichier original sur le disque dur. format gzip et le transférer avec algorithme de streaming tout ce qui peut fonctionner rapidement et sans consommation de disque dans des pipes unix :
gunzip remote_or_local_file.csv.gz | convert_to_sql | psql
Ainsi, l'idéal (le futur) est un option de serveur pour le format .csv.gz
.
Note après le commentaire de @CharlieClark : actuellement (2022) rien à faire, la meilleure alternative semble pgloader
STDIN :
gunzip -c file.csv.gz | pgloader --type csv ... - pgsql:///target?foo