J'ai construit un prototype de chargeur de données qui enregistre les CSV dans des tableaux évasés. Le flux de travail est le suivant :
-
Créez le schéma la première fois, par ex.
volatilitysurface
table :volatilitysurface::([date:`datetime$(); ccypair:`symbol$()] atm_convention:`symbol$(); premium_included:`boolean$(); smile_type:`symbol$(); vs_type:`symbol$(); delta_ratio:`float$(); delta_setting:`float$(); wing_extrapolation:`float$(); spread_type:`symbol$());
-
Pour chaque fichier dans le dossier rawdata, importez-le :
myfiles:@[system;"dir /b /o:gn ",string `$getenv[`KDBRAWDATA],"*.volatilitysurface.csv 2> nul";()]; if[myfiles~();.lg.o[`load;"no volatilitysurface files found!"];:0N]; .lg.o[`load;"loading data files ..."]; / load each file { mypath:"" sv (string `$getenv[`KDBRAWDATA];x); .lg.o[`load;"loading file name '",mypath,"' ..."]; myfile:hsym`$mypath; tmp1:select date,ccypair,atm_convention,premium_included,smile_type,vs_type,delta_ratio,delta_setting,wing_extrapolation,spread_type from update date:x, premium_included:?[premium_included = `$"true";1b;0b] from ("ZSSSSSFFFS";enlist ",")0:myfile; `volatilitysurface upsert tmp1; } @/: myfiles; delete tmp1 from `.; .Q.gc[]; .lg.o[`done;"loading volatilitysurface data done"]; .lg.o[`save;"saving volatilitysurface schema to ",string afolder]; volatilitysurface::0!volatilitysurface; .Q.dpft[afolder;`;`ccypair;`volatilitysurface]; .lg.o[`cleanup;"removing volatilitysurface from memory"]; delete volatilitysurface from `.; .Q.gc[]; .lg.o[`done;"saving volatilitysurface schema done"];
Cela fonctionne parfaitement. J'utilise .Q.gc[];
fréquemment pour éviter de heurter la wsfull
. Lorsque de nouveaux fichiers CSV sont disponibles, j'ouvre le schéma existant, je l'insère et le sauvegarde à nouveau, écrasant ainsi le système de fichiers HDB existant.
-
Schéma ouvert :
.lg.o[`open;"tables already exists, opening the schema ..."]; @[system;"l ",(string afolder) _ 0;{.lg.e[`open;"failed to load hdb directory: ", x]; 'x}]; / Re-create table index volatilitysurface::`date`ccypair xkey select from volatilitysurface;
-
Exécutez à nouveau l'étape 2 pour ajouter les nouveaux fichiers CSV aux fichiers existants.
volatilitysurface
le premier CSV est parfaitement inséré mais le deuxième CSV échoue avec :error: `cast
J'ai débogué jusqu'au point d'erreur et, pour vérifier, j'ai vu que les métadonnées de l'application tmp1
y volatilitysurface
sont parfaitement identiques. Avez-vous une idée de la raison pour laquelle cela se produit ? J'ai le même problème avec n'importe quelle autre table. J'ai essayé de nettoyer les clés de la table après chaque upsert, mais cela n'a pas aidé.
volatilitysurface::0!volatilitysurface;
volatilitysurface::`date`ccypair xkey volatilitysurface;
Et la comparaison des métadonnées au moment de l'erreur de distribution :
meta tmp1
c | t f a
------------------| -----
date | z
ccypair | s
atm_convention | s
premium_included | b
smile_type | s
vs_type | s
delta_ratio | f
delta_setting | f
wing_extrapolation| f
spread_type | s
meta volatilitysurface
c | t f a
------------------| -----
date | z
ccypair | s p
atm_convention | s
premium_included | b
smile_type | s
vs_type | s
delta_ratio | f
delta_setting | f
wing_extrapolation| f
spread_type | s
UPDATE En m'inspirant de la réponse ci-dessous, j'ai essayé d'utiliser le système Torq. .loader.loadallfiles
comme ceci (elle n'échoue pas mais rien ne se passe non plus, la table n'est pas créée en mémoire et les données ne sont pas écrites dans la base de données) :
.loader.loadallfiles[`headers`types`separator`tablename`dbdir`dataprocessfunc!(`x`ccypair`atm_convention`premium_included`smile_type`vs_type`delta_ratio`delta_setting`wing_extrapolation`spread_type;"ZSSSSSFFFS";enlist ",";`volatilitysurface;`:hdb; {[p;t] select date,ccypair,atm_convention,premium_included,smile_type,vs_type,delta_ratio,delta_setting,wing_extrapolation,spread_type from update date:x, premium_included:?[premium_included = `$"true";1b;0b] from t}); `:rawdata]
UDPATE2 C'est la sortie que j'obtiens de TorQ :
2017.11.20D08:46:12.550618000|wsp18497wn|dataloader|dataloader1|INF|dataloader|**** LOADING :rawdata/20171102_113420.disccurve.csv ****
2017.11.20D08:46:12.550618000|wsp18497wn|dataloader|dataloader1|INF|dataloader|reading in data chunk
2017.11.20D08:46:12.566218000|wsp18497wn|dataloader|dataloader1|INF|dataloader|Read 10000 rows
2017.11.20D08:46:12.566218000|wsp18497wn|dataloader|dataloader1|INF|dataloader|processing data
2017.11.20D08:46:12.566218000|wsp18497wn|dataloader|dataloader1|INF|dataloader|Enumerating
2017.11.20D08:46:12.566218000|wsp18497wn|dataloader|dataloader1|INF|dataloader|writing 4525 rows to :hdb/2017.09.12/volatilitysurface/
2017.11.20D08:46:12.581819000|wsp18497wn|dataloader|dataloader1|INF|dataloader|writing 4744 rows to :hdb/2017.09.13/volatilitysurface/
2017.11.20D08:46:12.659823000|wsp18497wn|dataloader|dataloader1|INF|dataloader|writing 731 rows to :hdb/2017.09.14/volatilitysurface/
2017.11.20D08:46:12.737827000|wsp18497wn|dataloader|dataloader1|INF|init|retrieving sort settings from :C:/Dev/torq//config/sort.csv
2017.11.20D08:46:12.737827000|wsp18497wn|dataloader|dataloader1|INF|sort|sorting the volatilitysurface table
2017.11.20D08:46:12.737827000|wsp18497wn|dataloader|dataloader1|INF|sorttab|No sort parameters have been specified for : volatilitysurface. Using default parameters
2017.11.20D08:46:12.737827000|wsp18497wn|dataloader|dataloader1|INF|sortfunction|sorting :hdb/2017.09.05/volatilitysurface/ by these columns : sym, time
2017.11.20D08:46:12.753428000|wsp18497wn|dataloader|dataloader1|ERR|sortfunction|failed to sort :hdb/2017.09.05/volatilitysurface/ by these columns : sym, time. The error was: hdb/2017.09.
J'obtiens l'erreur suivante sorttab|No sort parameters have been specified for : volatilitysurface. Using default parameters
où est documenté ce sorttab ? utilise-t-il la table PK par défaut ?
UPDATE3 Ok a corrigé UPDATE2 en fournissant une valeur par défaut de sort.csv
sous mon config
dossier :
tabname,att,column,sort
default,p,sym,1
default,,time,1
volatilitysurface,,date,1
volatilitysurface,,ccypair,1
Mais maintenant je vois que si j'appelle la fonction plusieurs fois sur les mêmes fichiers, elle ajoute simplement les données dupliquées au lieu de upsert
l'ingérer.
UPDATE4 Je n'y suis toujours pas arrivé... en supposant que je puisse vérifier qu'aucun fichier en double n'est utilisé. Lorsque je charge et démarre la base de données, je reçois une structure qui ressemble à une sorte de dictionnaire et non à une table.
2017.10.31| (,`volatilitysurface)!,+`date`ccypair`atm_convention`premium_incl..
2017.11.01| (,`volatilitysurface)!,+`date`ccypair`atm_convention`premium_incl..
2017.11.02| (,`volatilitysurface)!,+`date`ccypair`atm_convention`premium_incl..
2017.11.03| (,`volatilitysurface)!,+`date`ccypair`atm_convention`premium_incl..
sym | `AUDNOK`AUDCNH`AUDJPY`AUDHKD`AUDCHF`AUDSGD`AUDCAD`AUDDKK`CADSGD`C..
Notez que date est en fait datetime Z et pas seulement date. Ma version complète et la plus récente de l'invocation de la fonction est la suivante :
target:hsym `$("" sv ("./";getenv[`KDBHDB];"/volatilitysurface"));
rawdatadir:hsym `$getenv[`KDBRAWDATA];
.loader.loadallfiles[`headers`types`separator`tablename`dbdir`partitioncol`dataprocessfunc!(`x`ccypair`atm_convention`premium_included`smile_type`vs_type`delta_ratio`delta_setting`wing_extrapolation`spread_type;"ZSSSSSFFFS";enlist ",";`volatilitysurface;target;`date;{[p;t] select date,ccypair,atm_convention,premium_included,smile_type,vs_type,delta_ratio,delta_setting,wing_extrapolation,spread_type from update date:x, premium_included:?[premium_included = `$"true";1b;0b] from t}); rawdatadir];