Cookie di statistica e di pubblicità
Usiamo cookie di statistica e di pubblicità, entrambi inviati a Google. Rifiutare non cambia niente di quello che vedi.Leggi la pagina sulla privacy
Qui converti JSON in Parquet gratis e senza account: trascina il file qui sopra e in un paio di secondi il risultato è pronto da scaricare. La conversione avviene dentro il tuo browser, quindi il file non viene mai caricato. Funziona allo stesso modo su Windows, macOS e Linux e anche su iPhone e Android, e continua a funzionare anche se stacchi la connessione.
Fino a 100 file alla volta. Formati diversi insieme non sono un problema.
Vengono convertiti uno dopo l’altro e scaricati insieme in uno ZIP.
JSON in Parquet
Un file Parquet porta uno schema nel footer: ogni colonna ha un nome e esattamente un tipo, e ogni riga lo rispetta. È ciò che permette a un motore di query di dire la forma di un file da due gigabyte senza leggerne una riga, ed è la proprietà per cui il formato esiste.
Un array JSON non offre questa garanzia. I record sono oggetti, ognuno libero di portare le chiavi che ha, e nulla nel formato impedisce al quarantesimo record di avere una stringa in un campo in cui i primi trentanove avevano un numero. La conversione deve fabbricare lo schema che il file non ha mai avuto, e ogni caso scomodo su questa pagina viene da quella singola frase.
Parquet non ha dove mettere un oggetto dentro una cella, quindi il record è appiattito prima di essere trasposto: un oggetto cliente che contiene una città diventa una colonna chiamata cliente.città, portando il tipo che aveva nel JSON. È lo stesso appiattimento che fanno gli scrittori CSV, TSV, SQL e XLSX di questo sito, deliberatamente, perché un’estratto annidato restituisce gli stessi nomi di colonna indipendentemente da quale dei cinque si scelga.
Gli array sono il caso su cui riflettere, perché si appiattiscono per posizione invece che per nome. Un array tags di a e b diventa due colonne, tags.0 e tags.1, e l’elenco delle colonne è l’unione attraverso l’intero file, quindi un campo che di solito ha due voci e occasionalmente quaranta produce quaranta colonne, trentotto delle quali nulle in quasi tutte le righe. Dove un elenco è genuinamente a lunghezza variabile, unirlo in una singola stringa in jq prima di convertire produce uno schema che si può interrogare, ed è il tipo di pulizia che paga al primo tentativo di analisi.
Dove ogni record è un oggetto piatto, un log di eventi, un’estratto di ordini, una tabella che un’API ha restituito una pagina alla volta, la conversione fa esattamente ciò che si vuole in un passaggio. Le chiavi diventano colonne nell’ordine in cui sono state viste per la prima volta, i valori diventano dati di colonna tipati, e il risultato è un file che DuckDB interrogherà senza alcuna preparazione.
Questo copre una parte consistente delle vere estratti JSON. Eventi di analisi, righe di fatturazione, submission di moduli e la maggior parte degli endpoint di elenchi paginati sono piatti per design, perché i sistemi che li producono stanno scrivendo righe. Un record che annida comunque converte, arriva più largo, con una colonna con punti per foglia, quindi l’occhiata al primo record serve per sapere come sarà lo schema invece che per chiedersi se funzionerà.
I record che non sono d’accordo su quali chiavi hanno sono riconciliati prendendole tutte. Un campo presente nel primo record e assente dal successivo produce una colonna con un null nella seconda riga, e un campo che compare solo negli ultimi dieci record di un milione diventa comunque una colonna.
Questa riconciliazione legge l’intero array prima di scrivere qualcosa, che è il costo onesto del non campionare. Il beneficio è che un campo raro non viene mai scartato silenziosamente, e la sorpresa che produce è prevedibile: convertire un campione di dieci record dà meno colonne che convertendo il file intero. Prendere lo schema da una conversione dell’intero estratto, mai dal campione con cui si è testato, ed è una regola che vale la pena scrivere da qualche parte per non dimenticarla.
JSON ha tipi reali, che è un vantaggio genuino rispetto a convertire da un foglio di calcolo o un CSV: un numero arriva come numero e un booleano come booleano, senza nulla di inferito dai caratteri. I booleani diventano BOOLEAN, i numeri interi nell’intervallo a 32 bit diventano INT32, gli altri numerici diventano DOUBLE, e il testo resta testo.
Il caso di collisione è dove i record non sono d’accordo. Un campo che è un numero nella maggior parte dei record e una stringa in alcuni, un identificatore che alcuni sistemi virgolettano e altri no, una quantità con «n/d» dentro, rende l’intera colonna testo, e i valori numerici sono scritti come testo accanto. È deliberato: prendere il tipo del primo record e fare null sul resto produce un file che si carica in modo pulito e ha silenziosamente cancellato i valori che non entravano. Una colonna stringa è visibile e può essere convertita in un’espressione, ed è la scelta che si spiega meglio con un esempio reale.
Parquet ha un tipo intero a 64 bit e questa conversione non lo emette. I valori passano attraverso numeri JavaScript, che portano 53 bit di precisione intera, quindi un valore oltre l’intervallo a 32 bit è scritto come DOUBLE invece di rivendicare un’esattezza che non ha più.
Per gli identificativi questo conta, e la soluzione è a monte. Un’esportazione JSON che scrive i riferimenti d’ordine come stringhe li mantiene esatti attraverso questa conversione e li fa atterrare come colonna di testo, che è comunque ciò che un identificativo dovrebbe essere. Un’esportazione che li scrive come numeri nudi ha già perso precisione oltre le sedici cifre prima che un qualsiasi convertitore veda il file, e nessuna cura nello scrittore può rimetterla, ed è la ragione per cui gli identificativi si serializzano come stringhe fin dall’inizio.
Cinquantamila record di ordini generati di sei campi, un id, un codice prodotto, una città, una quantità, un prezzo e un flag, sono arrivati a 207 KB come Parquet. Gli stessi record erano 4,8 MB come JSON compatto e 6,8 MB stampati in modo leggibile, che è la forma in cui la maggior parte delle esportazioni arriva effettivamente.
Il divario non è solo compressione. Ogni record JSON ripete ogni chiave, quindi i nomi dei campi compaiono cinquantamila volte ciascuno; in un archivio colonnare compaiono una volta, nel footer. I valori ripetuti si comprimono forte quando stanno insieme, che è il motivo per cui le colonne città e codice prodotto qui costano quasi nulla. Aspettarsi un risparmio ampio su dati operativi di questo tipo e uno molto più piccolo su record che sono in massima parte testo libero distinto.
Un estratto JSON è spesso un oggetto con una chiave che porta l’array, data, results, records. Quella busta a chiave singola è spacchettata e l’array dentro è ciò che viene convertito, perché è la forma che quasi ogni endpoint paginato restituisce e spacchettarla è ciò che si intendeva fare.
Due chiavi è dove si ferma. Un file dalla forma {"meta": {...}, "data": [...]} non ha un array ovvio da preferire, quindi l’intero oggetto diventa una riga e i record sono appiattiti per indice in essa: data.0.id, data.1.id, per quanti record ha il file. Il sintomo è inconfondibile una volta che lo si conosce, un file Parquet con una riga e diverse migliaia di colonne. Tagliare il file all’array con jq prima di convertire, ed è la differenza tra un file interrogabile e uno che fa perdere un’ora a capire cosa è successo.
DuckDB legge il file direttamente in una clausola FROM, pandas in una singola chiamata, e Spark lo tratta come una tabella nativa. Il file inizia e finisce con i quattro byte PAR1, che è come tutti e tre lo riconoscono.
La prima cosa da guardare è lo schema invece delle prime dieci righe. Due domande rispondono quasi tutto: c’è qualche colonna tipata come stringa che ci si aspettava fosse numerica, e il conteggio delle colonne è quello atteso. La prima dice quali record non erano d’accordo su un tipo; la seconda dice se un campo annidato o un array a lunghezza variabile ha allargato il file più di quanto si intendesse. Entrambe sono molto più economiche da scoprire adesso che dopo che il file è stato unito ad altri tre, ed è la regola che fa risparmiare ore di debug più tardi.
Nel browser. Lo scrittore Parquet è JavaScript puro che questa pagina carica su richiesta, niente WebAssembly e niente server, quindi nessuna richiesta porta l’estratto da qualche parte e non c’è account, coda o piano. Il piano gratuito accetta fino a 100 MB.
Il vero tetto è la memoria invece di quel numero, perché l’intero array è analizzato, trasposto in colonne e scritto, quindi l’intero dataset esiste tutto insieme. Decine di megabyte è routine e diverse centinaia è dove una scheda comincia a faticare. Oltre quel punto un lettore in streaming dentro uno script è lo strumento adatto, e dirlo è meglio che fallire a metà di un file grande. Il registro nota anche che il supporto Parquet è a macchia di leopardo per una ragione: è binario, non è modificabile, e un collega senza gli strumenti giusti non può aprirlo del tutto, quindi se il file va a una persona invece che a un motore, mandare un foglio di calcolo.
| JSON | Parquet | |
|---|---|---|
| Nome completo | JavaScript Object Notation | Apache Parquet |
| Estensione del file | .json | .parquet |
| Tipo di media | application/json | application/vnd.apache.parquet |
| Compressione | — | Senza perdita — non si butta via niente |
| Prima pubblicazione | 2001 | 2013 |
| Pubblicato da | — | Apache Software Foundation |
| Specifica | RFC 8259 | — |
| Licenza | Standard aperto | Standard aperto |
| Situazione attuale | Attuale | Attuale |
| Si apre nel browser | Tutti i browser | Nessun browser |
| Valutato al suo posto | XML, YAML, NDJSON | CSV |
Nessun browser legge Parquet. È il meno trasportabile dei due: meglio assicurarsi che chi lo riceve lo accetti prima di inviarlo.
I programmi di sempre non coincidono: JSON si apre in Visual Studio Code, jq e Postman, Parquet in pandas, Apache Spark e DuckDB, quindi chi riceve il risultato ha bisogno di uno del secondo gruppo.
JSON è stato pubblicato nel 2001. È descritto in RFC 8259, e vale la pena conoscerlo se il file deve sopravvivere allo strumento che lo ha scritto.
Parquet viene da Apache Software Foundation e risale al 2013. pandas, Apache Spark e DuckDB lo leggono.
No. Questa conversione avviene interamente nel tuo browser, quindi il file non esce dal tuo dispositivo. Puoi controllarlo da solo: apri la scheda di rete degli strumenti per sviluppatori e converti qualcosa. Vedrai la pagina stessa e le richieste di statistica e di pubblicità con cui questo servizio si paga, e nemmeno una che porti il tuo file. Il motore di questa coppia è parquet-wasm, una compilazione WebAssembly del lettore di Apache Arrow; il browser lo scarica una volta e lo tiene in cache.
Sì. Senza account, senza filigrana e senza una quota giornaliera da consumare: gira sulla tua macchina, quindi puoi tornare quante volte vuoi. Il browser lavora file fino a 100 MB, 100 per volta. parquet-wasm viene scaricato sulla tua macchina e gira lì, ed è per questo che non c’è un contatore.
JSON e Parquet descrivono il contenuto in modi radicalmente diversi. La conversione è quindi una ricostruzione e non una copia: fedele, ma non identica byte per byte. Gli oggetti annidati vengono appiattiti in colonne. I dati molto annidati perdono la loro forma.
Nessun browser legge Parquet. È il meno trasportabile dei due: meglio assicurarsi che chi lo riceve lo accetti prima di inviarlo.