Cookies voor statistiek en advertenties
We gebruiken cookies voor statistiek en voor advertenties, allebei naar Google. Weigeren verandert niets aan wat je te zien krijgt.Lees de privacypagina
Hier zet je JSON naar Parquet om, gratis en zonder account: sleep het bestand hierboven erin en binnen een paar seconden staat het resultaat klaar om te downloaden. De omzetting gebeurt binnen je eigen browser, dus het bestand wordt nooit geüpload. Het werkt hetzelfde op Windows, macOS en Linux als op iPhone en Android, en het blijft werken als je de verbinding verbreekt.
Tot 100 bestanden tegelijk. Verschillende formaten door elkaar is prima.
Ze worden een voor een omgezet en samen in één ZIP gedownload.
JSON naar Parquet
Een Parquet-bestand draagt een schema in zijn voettekst: elke kolom heeft een naam en precies één type, en elke rij houdt zich daaraan. Dat is wat een query-engine in staat stelt om zonder een rij te lezen te vertellen hoe een bestand van twee gigabyte eruitziet, en het is precies de eigenschap waarvoor het formaat bestaat.
Een JSON-array biedt zo’n garantie niet. De records zijn objecten, elk vrij om te dragen welke sleutels het maar wil, en niets in het formaat verhindert dat het veertigste record een tekst bevat in een veld waar de eerste negenendertig een getal hadden. De omzetting moet dus het schema construeren dat het bestand nooit had, en elk lastig geval hieronder komt uit die ene zin voort.
Parquet heeft geen plek voor een object binnen een cel, dus het record wordt eerst plat geslagen voordat het wordt getransponeerd: een klantobject met een woonplaats wordt een kolom genaamd customer.city, met het type dat het in de JSON had. Dit is dezelfde platslag die de CSV-, TSV-, SQL- en XLSX-schrijvers op deze site toepassen — met opzet, zodat één geneste export overal dezelfde kolomnamen oplevert.
Arrays zijn het geval om over na te denken, want die worden op positie plat geslagen in plaats van op naam. Een tags-array van a en b wordt twee kolommen, tags.0 en tags.1, en de kolomlijst is de vereniging over het hele bestand — dus een veld dat meestal twee elementen heeft en af en toe veertig levert veertig kolommen op, waarvan achtendertig leeg in bijna elke rij. Waar een lijst echt variabele lengte heeft, geeft het samenvoegen tot één string met jq voordat je omzet een schema op dat je kunt bevragen.
Waar elk record al een plat object is — een gebeurtenislog, een export van bestellingen, een tabel die een API pagina voor pagina teruggaf — doet de omzetting precies wat je wilt en in één stap. De sleutels worden kolommen in de volgorde waarin ze voor het eerst voorkwamen, de waarden worden getypeerde kolomdata, en het resultaat is een bestand dat DuckDB zonder voorbereiding bevraagt.
Dat dekt een groot deel van echte JSON-exports. Analyseregistraties, factuurregels, formulierinzendingen en de meeste gepagineerde lijst-endpoints zijn plat van opzet, omdat de systemen die ze produceren rijen schrijven. Een record dat wél nest, zet nog steeds om — het komt breder aan, met een kolom per blad — dus een blik op het eerste record gaat er vooral om te weten hoe het schema eruit zal zien, niet of het werkt.
Records die het niet eens zijn over welke sleutels ze hebben, worden verzoend door alles samen te nemen. Een veld dat in het eerste record voorkomt en niet in het volgende, geeft in de tweede rij een lege waarde, en een veld dat pas in de laatste tien records van een miljoen voorkomt, wordt alsnog een kolom.
Die verzoening leest het hele bestand voordat er iets wordt weggeschreven, wat de eerlijke prijs is van niet steekproefsgewijs werken. Het voordeel is dat een zeldzaam veld nooit stilzwijgend verdwijnt, en de verrassing die het oplevert is voorspelbaar: een steekproef van tien records omzetten geeft minder kolommen dan het hele bestand. Neem het schema van een omzetting van de volledige export, nooit van de steekproef waarmee je testte.
JSON heeft echte types, wat een echt voordeel is boven omzetten vanuit een spreadsheet of CSV: een getal komt aan als getal en een boolean als boolean, zonder dat er iets uit tekens wordt afgeleid. Booleans worden BOOLEAN, gehele getallen binnen het 32-bits bereik worden INT32, al het overige numerieke wordt DOUBLE, en tekst blijft tekst.
Het botsingsgeval is waar records het oneens zijn. Een veld dat in de meeste records een getal is en in een paar een tekst — een identificatienummer dat sommige systemen aanhalen en andere niet, een hoeveelheid met "n.v.t." erin — maakt de hele kolom tekst, met de numerieke waarden als tekst ernaast. Dat is bewust: het type van het eerste record nemen en de rest nulleren, zou een bestand opleveren dat probleemloos laadt en stilletjes waarden heeft weggegooid die niet pasten. Een tekstkolom is zichtbaar en met één expressie om te zetten.
Parquet heeft een 64-bits geheeltalig type en deze omzetting schrijft dat niet weg. De waarden lopen via JavaScript-getallen, die 53 bits gehele precisie dragen, dus een waarde buiten het 32-bits bereik wordt als DOUBLE geschreven in plaats van een exactheid te claimen die hij niet meer heeft.
Voor identificatienummers doet dat ertoe, en de oplossing ligt stroomopwaarts. Een JSON-export die bestelreferenties als string schrijft, houdt ze exact door deze omzetting heen en levert een tekstkolom op, wat een identificatienummer sowieso zou moeten zijn. Een export die ze als kaal getal schrijft, is al precisie kwijt voorbij zestien cijfers voordat welke converter dan ook het bestand ziet.
Vijftigduizend gegenereerde bestelrecords van zes velden — een id, een productcode, een plaats, een hoeveelheid, een prijs en een vlag — kwamen uit op 207 KB als Parquet. Dezelfde records waren 4,8 MB als compacte JSON en 6,8 MB met opmaak, wat de vorm is waarin de meeste exports daadwerkelijk aankomen.
Het verschil zit niet alleen in compressie. Elk JSON-record herhaalt elke sleutel, dus veldnamen komen vijftigduizend keer voor; in een kolomopslag staan ze eenmaal, in de voettekst. Herhaalde waarden comprimeren goed als ze bij elkaar staan, wat verklaart waarom de kolommen plaats en productcode hier bijna niets kosten. Verwacht een grote besparing op operationele data van dit soort en een veel kleinere op records die grotendeels unieke vrije tekst zijn.
Een JSON-export is vaak een object met één sleutel die de array bevat — data, results, records. Dat enkele-sleutel-omhulsel wordt voor je uitgepakt en de array daarbinnen wordt omgezet, omdat dat de vorm is die vrijwel elk gepagineerd endpoint teruggeeft, en uitpakken is wat bedoeld was.
Bij twee sleutels stopt dat. Een bestand in de vorm {"meta": {...}, "data": [...]} heeft geen voor de hand liggende array om te kiezen, dus het hele object wordt één rij en de records worden op index plat geslagen erin: data.0.id, data.1.id, en zo verder voor zoveel records als het bestand bevat. Het symptoom is onmiskenbaar zodra je het kent — een Parquet-bestand met één rij en enkele duizenden kolommen. Snoei het bestand met jq tot de array voordat je omzet.
DuckDB leest het bestand rechtstreeks in een FROM-clausule, pandas in één aanroep, en Spark behandelt het als een natuurlijke tabel. Het bestand begint en eindigt met de vier bytes PAR1, waaraan elk van hen het herkent.
Kijk eerst naar het schema in plaats van naar de eerste tien rijen. Twee vragen beantwoorden bijna alles: is een kolom als tekst getypeerd terwijl je numeriek verwachtte, en klopt het aantal kolommen met wat je verwachtte. De eerste vertelt welke records het oneens waren over een type; de tweede vertelt of een genest veld of een array met variabele lengte het bestand breder maakte dan bedoeld. Beide zijn veel goedkoper om nu te ontdekken dan nadat het bestand met drie andere is samengevoegd.
In de browser. De Parquet-schrijver is gewone JavaScript die deze pagina op aanvraag laadt — geen WebAssembly en geen server — dus geen verzoek draagt de export ergens naartoe, en er is geen account, wachtrij of abonnement. De gratis laag accepteert tot 100 MB.
De echte grens is geheugen, niet dat getal, want de hele array wordt geparst, in kolommen getransponeerd en weggeschreven, dus de volledige dataset bestaat in één keer. Tientallen megabytes is routine en enkele honderden is waar een tabblad begint te haperen. Voorbij dat punt is een streamende lezer in een script het juiste gereedschap, en dat vooraf zeggen is beter dan halverwege een groot bestand vastlopen.
| JSON | Parquet | |
|---|---|---|
| Volledige naam | JavaScript Object Notation | Apache Parquet |
| Bestandsextensie | .json | .parquet |
| Mediatype | application/json | application/vnd.apache.parquet |
| Compressie | — | Zonder verlies — er gaat niets weg |
| Voor het eerst gepubliceerd | 2001 | 2013 |
| Uitgegeven door | — | Apache Software Foundation |
| Specificatie | RFC 8259 | — |
| Licentie | Open standaard | Open standaard |
| Stand van zaken | Actueel | Actueel |
| Opent in een browser | Elke browser | Geen browser |
| In plaats daarvan overwogen | XML, YAML, NDJSON | CSV |
Geen enkele browser leest Parquet. Daarmee is het het minst draagbare van de twee. Ga liever na of de ontvanger het aanneemt voor je het verstuurt.
De gebruikelijke programma's overlappen niet: JSON open je in Visual Studio Code, jq en Postman, Parquet in pandas, Apache Spark en DuckDB — wie het resultaat krijgt, heeft dus iets uit de tweede rij nodig.
JSON verscheen in 2001. Het is vastgelegd in RFC 8259, en dat is de moeite waard als het bestand het gereedschap moet overleven dat het schreef.
Parquet komt van Apache Software Foundation en stamt uit 2013. pandas, Apache Spark en DuckDB lezen het formaat.
Nee. Deze omzetting gebeurt volledig in je browser, dus het bestand verlaat je apparaat niet. Je kunt het zelf nagaan: open het netwerktabblad van de ontwikkelaarshulpmiddelen en zet iets om. Je ziet de pagina zelf en de verzoeken voor statistiek en advertenties waarmee deze dienst betaald wordt, en geen enkel verzoek dat je bestand meeneemt. De motor achter juist dit paar is parquet-wasm, een WebAssembly-versie van de Apache Arrow-lezer; je browser haalt die één keer op en bewaart hem.
Ja. Geen account, geen watermerk en geen dagtegoed dat opraakt: het draait op je eigen machine, dus je mag zo vaak terugkomen als je wilt. De browser verwerkt bestanden tot 100 MB, 100 tegelijk. parquet-wasm wordt naar je eigen machine gehaald en draait daar, en daarom staat er geen teller op.
JSON en Parquet beschrijven de inhoud op fundamenteel andere manieren. De omzetting is daarom een reconstructie en geen kopie: getrouw, maar niet byte voor byte identiek. Geneste objecten worden platgeslagen tot kolommen. Diep geneste gegevens verliezen hun vorm.
Geen enkele browser leest Parquet. Daarmee is het het minst draagbare van de twee. Ga liever na of de ontvanger het aanneemt voor je het verstuurt.