JSON
La méga-brick JSON enchaîne plusieurs opérations sur des données JSON, dans
l'ordre déclaré : aplatir une structure imbriquée en colonnes (flatten),
parser une chaîne JSON en objet (parse) ou sérialiser des colonnes en une
chaîne JSON (stringify).
Elle remplace les anciennes bricks Flatten JSON, From JSON et To JSON (voir Bricks héritées).
| Entrées | Sorties |
|---|---|
in : le flux de données | out : le flux transformé |
Une opération dont la colonne cible n'existe pas dans le flux est ignorée
silencieusement : le flux passe inchangé. En revanche, un JSON invalide
(flatten, parse) fait échouer l'exécution.
flatten : aplatir une structure
Déplie une colonne contenant un objet imbriqué (ou une chaîne JSON) en autant de colonnes que de champs. Les nouvelles colonnes sont préfixées du nom de la colonne d'origine, les niveaux étant joints par le séparateur.
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
column | string | — | Colonne à aplatir (objet ou chaîne JSON). |
separator | string | . | Séparateur entre les niveaux imbriqués. |
drop_source | booléen | true | Supprime la colonne d'origine après aplatissement. |
prefix | string | le nom de la colonne | Préfixe des colonnes produites. Vide = aucun préfixe, les clés donnent les noms. |
Avant, colonne client :
| id | client |
|---|---|
| 1 | {"nom": "Dupont", "adresse": {"ville": "Lyon"}} |
Après (separator: ".", drop_source: true) :
| id | client.nom | client.adresse.ville |
|---|---|---|
| 1 | Dupont | Lyon |
explode : éclater un tableau en lignes
La seule opération qui change le nombre de lignes : chaque élément du tableau devient une ligne, l'entête étant recopiée sur chacune.
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
column | string | — | Colonne qui porte le tableau. |
path | string | (racine) | Chemin pointé vers le tableau (facture.lignes). |
keep_columns | liste | toutes | Colonnes d'entête reportées sur chaque ligne. |
output_name | string | (vide) | Colonne qui reçoit l'élément entier. Vide = l'élément est éclaté en colonnes. |
prefix / separator | string | '' / . | Nomment les colonnes issues de l'éclatement. Sans objet si output_name est renseigné. |
drop_source | booléen | true | Supprime la colonne source. |
on_empty | string | ignorer | ignorer, conserver (garde l'entête seule) ou echouer. |
Deux façons de sortir le détail
Avec ID_FACTURE et une colonne ACTES portant
[{"CODE_ACTE": "A1", "QUANTITE": 1}, {"CODE_ACTE": "A2", "QUANTITE": 3}] :
Éclaté en colonnes — sans output_name :
| ID_FACTURE | CODE_ACTE | QUANTITE |
|---|---|---|
| F-1 | A1 | 1 |
| F-1 | A2 | 3 |
Gardé entier — output_name: LINE :
| ID_FACTURE | LINE |
|---|---|
| F-1 | {'CODE_ACTE': 'A1', 'QUANTITE': 1} |
| F-1 | {'CODE_ACTE': 'A2', 'QUANTITE': 3} |
Le second sert quand la ligne de détail doit voyager telle quelle : la
repasser dans une boucle, l'écrire d'un bloc, l'ouvrir plus loin. L'élément est
rangé comme une structure — celle que produit aussi parse — et reste donc
lisible par la brick.
Le parcours en deux étapes
Éclater, puis extraire — deux gestes qui se lisent et se règlent séparément :
explode column: ACTES keep_columns: [ID_FACTURE] output_name: LINE
flatten column: LINE prefix: (vide)
| ID_FACTURE | CODE_ACTE | QUANTITE |
|---|---|---|
| F-1 | A1 | 1 |
| F-1 | A2 | 3 |
Sans cela, les colonnes sortent en LINE.CODE_ACTE : la colonne porteuse
n'était qu'un intermédiaire, et il faudrait renommer colonne par colonne
derrière.
Nommer les colonnes avant de les écrire en aval
Les colonnes issues d'un aplatissement viennent du contenu du document, pas
de la configuration : ni le studio ni le moteur ne peuvent les deviner. Chaque
flatten et chaque explode porte donc son JSON d'exemple, replié sous le
nom de la colonne qu'il ouvre.
L'exemple ne configure rien : il ne part jamais au runner, et ne change pas une ligne de ce que la brick fait. Il sert à annoncer les colonnes, pour qu'on cesse d'écrire de mémoire des noms qu'on ne découvrirait inexistants qu'à l'exécution.
Dans un « éclater puis extraire », le premier geste voit le tableau et le second l'élément : ce ne sont pas les mêmes colonnes. Un exemple unique ne pouvait décrire que le premier, et le second n'annonçait rien.
Déclarer le type d'une colonne produite
Les types d'un aplatissement sont devinés par pandas depuis les valeurs : un
1 sans guillemets sort en int64, un 0 de TVA aussi. Chaque colonne
déduite porte donc un sélecteur de type, sous l'exemple.
Tant que rien n'est déclaré, il affiche « Deviné (Texte) » — et c'est une information, pas un réglage.
Un repr relu depuis une base écrit 'QUANTITE': '1', entre quotes, donc du
texte — là où le document réel porte "QUANTITE": 1, un nombre. Le type
deviné vient de l'exemple, pas de la donnée : voir « Texte » ne veut pas dire
qu'on en aura. Il faut le déclarer.
Le type déclaré est appliqué — pas seulement annoncé. C'est le paramètre
types de l'opération, et il part au runner :
flatten column: LINE prefix: (vide) types: { QUANTITE: string }
sans types | avec types: { QUANTITE: string } |
|---|---|
QUANTITE → 1 (entier) | QUANTITE → '1' (texte) |
Ces types n'ont d'abord servi qu'à l'affichage. C'était pire que pas de réglage du tout : le contrat de sortie enregistrait « Texte », le flux portait un entier, et la brick d'aval refusait l'entrée —
Contrat de schéma non respecté — « QUANTITE_STR » attendu Texte (string)
mais reçu int64
— sur un écart que l'écran avait lui-même créé.
Un type posé sur une colonne que le document ne porte plus est simplement ignoré : le réglage est périmé, pas fautif.
Ce qu'on fait d'une valeur illisible
on_cast_error | Effet |
|---|---|
echouer (défaut) | La brick s'arrête, en nommant la colonne. |
ecarter | La ligne part sur la sortie « Non convertible », les autres continuent converties. |
Arrêter est le défaut : sur un flux interne, un mauvais type est un défaut de programme. Sur des données venues du dehors, non — dix mille factures dont trente portent un montant illisible ne doivent pas être perdues tout entières.
La sortie « Non convertible » porte les valeurs telles qu'elles sont
arrivées — c'est ce qui a été reçu qu'il faut lire pour comprendre — plus une
colonne _cast_error qui dit pourquoi. Les motifs d'une même ligne y sont
réunis, séparés par ; :
« QUANTITE » ne se lit pas comme « integer » : 'trop'; « MONTANT_HT » ne se lit pas comme « integer » : 'cher'
Les rendre un par un obligerait à suivre la même ligne de rejet en rejet pour savoir tout ce qui cloche, et à recommencer après chaque correction.
Il n'y avait rien à convertir, donc rien n'a échoué : la ligne continue et la
colonne reste vide. cast_empty_ok à faux la rejette au contraire — utile
quand la colonne est censée être toujours remplie, et que son vide est
justement l'anomalie qu'on cherche. Le motif dit alors « est vide », pas « ne se
lit pas ».
La sortie « Non convertible » est toujours émise, même vide. Une sortie qui n'existerait que les jours de rejet obligerait l'aval à se demander si rien n'a été écarté ou si la branche n'a pas tourné.
L'onglet Sortie montre le résultat de la chaîne entière, toutes opérations enchaînées.
explode, parse et flatten acceptent le JSON et le repr Python —
quotes simples, True/None — la forme ordinaire d'une liste relue depuis une
base. Un texte qui n'est ni l'un ni l'autre arrête la brick, en nommant la
colonne.
parse : chaîne JSON vers objet
Convertit une colonne contenant du JSON sous forme de chaîne en objet
manipulable par les opérations suivantes (par exemple un flatten juste après).
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
column | string | — | Colonne contenant la chaîne JSON. |
output_name | string | colonne source | Colonne de sortie (par défaut, remplace la colonne source). |
Avant : payload = "{\"statut\": \"ok\"}" (chaîne). Après : payload est un
objet dont les opérations suivantes peuvent lire les champs.
stringify : colonnes vers chaîne JSON
Sérialise plusieurs colonnes en une colonne contenant un objet JSON par
ligne. Pratique avant un export vers une API ou une colonne jsonb.
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
columns | liste | — | Colonnes à inclure dans l'objet JSON (seules celles présentes dans le flux sont prises). |
output_name | string | — | Colonne de sortie (requis ; sans elle, l'opération est ignorée). |
Avant :
| nom | ville |
|---|---|
| Dupont | Lyon |
Après (columns: [nom, ville], output_name: doc) :
| nom | ville | doc |
|---|---|---|
| Dupont | Lyon | {"nom": "Dupont", "ville": "Lyon"} |
Bonnes pratiques
- Ordre des opérations :
parseavantflattenn'est pas nécessaire,flattenparse lui-même les chaînes JSON. Utilisezparseseul quand vous voulez garder l'objet sans l'aplatir. - Séparateur : gardez
.sauf si vos champs JSON contiennent déjà des points ; un séparateur_produit des noms de colonnes plus faciles à requêter en SQL. - Exemple : donnez-le sur l'opération qui ouvre la colonne, pas sur la brick — dans un « éclater puis extraire », les deux gestes ne voient pas les mêmes colonnes.
- Colonnes de sortie : après un
flatten, une brick Colonnes permet de renommer, supprimer, ou ne garder que les colonnes générées.
Voir aussi : Bricks héritées.