Cara Meratakan JSON Bersarang ke CSV: 5 Strategi & Matriks Keputusan
Masalah Geometri
Anda selalu menabrak dinding yang sama. Sebuah API mengembalikan JSON bersarang (nested JSON) dan analis di Slack hanya ingin sebuah spreadsheet. mongoexport menghasilkan pembungkus $oid dan tiga lapis metadata, sedangkan BigQuery mengharapkan tabel datar. Meratakan JSON bersarang ke CSV bukan masalah sintaks. Ini masalah geometri. JSON adalah pohon, CSV adalah grid, dan Anda tidak bisa memindahkan pohon ke dalam grid tanpa memilih bagaimana cabang-cabangnya runtuh.
Ada tepat lima strategi untuk meruntuhkannya. Pilih yang salah dan Anda mengirim 200 kolom ke Excel, kehilangan presisi pada ID Twitter, atau merusak round-trip yang menjadi tumpuan pipeline Anda. Pilih yang tepat dan konversinya cukup satu baris.
| Strategi | Satu baris | Cocok untuk |
|---|---|---|
| Notasi titik | customer.address.city | Analisis Excel/Sheets |
| Garis bawah | customer_address_city | Kolom ramah SQL |
| Array terindeks | items.0.sku, items.1.sku | Array berukuran tetap |
| Ekspansi baris | Ulang induk untuk setiap anak | Analitik Pandas/BigQuery |
| Stringify | "{\"city\":\"Seattle\"}" dalam satu sel | Round-trip tanpa kehilangan data |
Panduan ini menelusuri setiap strategi, memberi Anda matriks keputusan berdasarkan konsumen (Excel, Pandas, BigQuery, Postgres), dan menunjukkan empat payload nyata di mana strategi yang tepat bukanlah yang paling jelas. Jika Anda juga membutuhkan ikhtisar bidirectional umum (pustaka parser, streaming, jebakan encoding), lihat Konversi CSV ke JSON: Metode, Jebakan & Contoh Kode.
Mengapa JSON Bersarang Tidak Pas dengan CSV
JSON membawa tiga jenis struktur yang tidak dimiliki CSV. Hierarki adalah objek di dalam objek. Urutan adalah array. Campuran adalah kombinasi keduanya: array berisi objek, objek dengan array, array berisi array. Sebuah pesanan e-commerce tipikal mengandung ketiganya sekaligus.
CSV hanya memiliki dua dimensi: baris dan kolom. Tidak ada sumbu ketiga untuk “kolom ini memuat tiga anak”. Ketika Anda menuntut grid dari sebuah pohon, sesuatu harus mengalah. Entah menyebarkan anak-anak ke lebih banyak kolom (dan menerima nama seperti items.0.options.0.value), menyebarkannya ke lebih banyak baris (field induk berulang), atau menjejalkannya ke dalam satu sel sebagai teks dan berhenti memperlakukannya sebagai struktur.
Setiap strategi di bawah ini menjawab pertanyaan itu dengan cara berbeda. Sebagian mempertahankan keterbacaan dan mengorbankan keamanan round-trip. Sebagian lain melakukan sebaliknya. Tidak ada yang universal. Cocokkan jawaban dengan siapa yang membaca file selanjutnya.
Perbandingan 5 Strategi Pemerataan
Strategi 1: Notasi Titik (customer.address.city)
Notasi titik berjalan dari akar ke daun dan menggunakan . untuk menggabungkan key. Setiap objek bersarang menjadi satu kolom per daun, dengan jalur ter-encode dalam nama kolom.
{ "customer": { "address": { "city": "Seattle" } }, "email": "alice@example.com" }
menjadi
customer.address.city,email
Seattle,alice@example.com
Di Pandas, satu baris sudah cukup:
import pandas as pd
data = [{"customer": {"address": {"city": "Seattle"}}, "email": "alice@example.com"}]
df = pd.json_normalize(data, sep='.')
df.to_csv("out.csv", index=False)
Di JavaScript, fungsi rekursif kecil sudah memadai:
function flattenDot(obj, prefix = '', acc = {}) {
for (const [k, v] of Object.entries(obj)) {
const key = prefix ? `${prefix}.${k}` : k;
if (v && typeof v === 'object' && !Array.isArray(v)) {
flattenDot(v, key, acc);
} else {
acc[key] = v;
}
}
return acc;
}
Kelebihan: mudah dibaca manusia, default Pandas, mempertahankan jalur asli. Kekurangan: nama kolom bisa sangat panjang (spec Kubernetes menghasilkan nama seperti spec.template.spec.containers.0.resources.limits.memory), dan titik menjadi ambigu jika key sebenarnya mengandung . (parameter event Google Analytics 4 begitu).
Strategi 2: Notasi Garis Bawah (customer_address_city)
Ide yang sama, pemisah berbeda. Ganti . dengan _ dan hasilnya aman untuk SQL: SELECT customer_address_city FROM events berjalan tanpa perlu mengutip identifier. BigQuery, Snowflake, dan Postgres sama-sama lebih menyukai gaya ini.
import pandas as pd
df = pd.json_normalize(data, sep='_')
Pilihan antara titik dan garis bawah murni soal tool hilir. Analis Excel membaca titik lebih alami; engine SQL menerima garis bawah tanpa keluhan. Pindahkan dengan mengubah satu argumen.
Kelebihan: nama kolom aman SQL, identifier sesuai BigQuery, tidak perlu pengutipan. Kekurangan: ambiguitas tetap ada jika key mengandung _ (lebih jarang daripada . tapi tetap mungkin).
Strategi 3: Array Terindeks (items.0.sku, items.1.sku)
Objek meratakan dengan bersih karena key-nya unik. Array tidak demikian karena panjangnya tak terbatas. Strategi indeks memperlakukan posisi array sebagai segmen jalur: items[0] menjadi items.0.
{ "id": "ord-001", "items": [{"sku": "A"}, {"sku": "B"}] }
menjadi
id,items.0.sku,items.1.sku
ord-001,A,B
Ini perilaku default mode Flatten di Konverter JSON ke CSV kami. Setiap daun mendapat kolomnya sendiri; posisi dicatat dalam nama.
Kelebihan: setiap nilai memperoleh selnya sendiri, posisi tetap terjaga, tidak ada duplikasi baris. Kekurangan: jumlah kolom meledak (100 item = 100 kolom); baris dengan panjang array berbeda menghasilkan tabel tidak rata; agregasi hilir rusak (tidak ada SUM(items.*.qty)).
Strategi 4: Ekspansi Baris (array menjadi banyak baris)
Alih-alih melebarkan tabel agar muat array, panjangkan tabelnya. Ulangi field induk sekali per elemen array, dan biarkan setiap elemen menjadi barisnya sendiri.
{ "order_id": "ord-001", "customer": "Alice", "items": [{"sku": "A", "qty": 2}, {"sku": "B", "qty": 1}] }
menjadi
order_id,customer,items.sku,items.qty
ord-001,Alice,A,2
ord-001,Alice,B,1
Di Pandas, satu baris melakukan ekspansi sekaligus normalisasi:
import pandas as pd
orders = [{"order_id": "ord-001", "customer": "Alice",
"items": [{"sku": "A", "qty": 2}, {"sku": "B", "qty": 1}]}]
df = pd.json_normalize(orders, record_path='items', meta=['order_id', 'customer'])
df.to_csv("orders.csv", index=False)
Di SQL, UNNEST melakukan hal yang sama:
SELECT order_id, item.sku, item.qty FROM orders, UNNEST(items) AS item;
Kelebihan: Pandas dan BigQuery memperlakukan bentuk ini secara native, agregasi berjalan (GROUP BY order_id), skema tetap ramping. Kekurangan: field induk terduplikasi di setiap baris anak (membengkakkan penyimpanan), batas 1-ke-banyak bersifat implisit (Anda butuh order_id), dan dua array di level yang sama menghasilkan Cartesian product kecuali Anda meng-UNNEST keduanya dengan hati-hati.
Strategi 5: Stringify (JSON-dalam-sel)
Opsi radikal: jangan ratakan sama sekali. Serialisasi seluruh nilai bersarang sebagai string JSON dan tempatkan di satu sel. Tabel luar tetap datar; strukturnya terjaga utuh di dalam.
{ "id": "ord-001", "items": [{"sku": "A"}, {"sku": "B"}] }
menjadi
id,items
ord-001,"[{""sku"":""A""},{""sku"":""B""}]"
Ini mode Stringify di Konverter JSON ke CSV kami. Jumlah kolom tidak pernah meledak, bentuk asli terjaga byte-per-byte, dan perjalanan balik merekonstruksi input dengan persis.
Kelebihan: 100% tanpa kehilangan data, jumlah kolom dapat diprediksi, aman round-trip jika dipasangkan dengan Infer types saat membalikkan. Kekurangan: pengguna Excel melihat tanda kutip yang di-escape, engine SQL butuh fungsi JSON untuk menelusuri nilai (JSON_EXTRACT_SCALAR di BigQuery, ->>'key' di Postgres), dan rumus spreadsheet tidak bisa menjangkau isi sel.
5 Strategi Berdampingan
Input yang sama untuk kelimanya: {"id":"ord-001","customer":{"name":"Alice"},"items":[{"sku":"A","qty":2},{"sku":"B","qty":1}]}.
| Strategi | Kolom | Aman round-trip | Konsumen terbaik |
|---|---|---|---|
| Notasi titik | tumbuh seiring array | Tidak | Analis Excel |
| Garis bawah | tumbuh seiring array | Tidak | Data warehouse SQL |
| Array terindeks | 2 per slot array | Tidak (ambigu saat dibalik) | Array berukuran tetap |
| Ekspansi baris | ramping, 1 baris per anak | Sebagian (butuh key) | Pandas / BigQuery |
| Stringify | tetap | Ya | Round-trip pipeline |
Matriks Keputusan: Strategi Mana untuk Konsumen Mana
Cari konsumennya dulu, lalu baca strategi yang direkomendasikan.
| Konsumen | Strategi direkomendasikan | Alasan |
|---|---|---|
| Excel / Sheets (analis) | Titik + Stringify untuk array besar | Nama kolom mudah dibaca; array besar tidak meledakkan sheet |
| Excel-EU (DE/FR/IT/ES) | Titik + delimiter ; + UTF-8 BOM | Semicolon wajib; BOM mencegah encoding kacau |
Pandas (json_normalize + explode) | Garis bawah + Ekspansi baris | Kolom ramah SQL; ekspansi cocok dengan groupby |
| BigQuery / Snowflake | TSV + Stringify atau Ekspansi | Tab menghindari jebakan tanda kutip; JSON_EXTRACT menelusuri sel |
PostgreSQL COPY | RFC 4180 + Garis bawah + datar | Kolom aman SQL; pengutipan RFC ketat |
| MongoDB → BigQuery ETL | Muat NDJSON langsung, lewati CSV | BigQuery memuat NDJSON secara native; CSV adalah jalan memutar |
Excel / Google Sheets: Jebakan Locale
Nama kolom Excel praktis tidak terbatas panjangnya. Jebakan sebenarnya ada tiga.
Pertama, pemisahan locale. Excel versi Eropa (Jerman, Prancis, Italia, Spanyol) mengharapkan ; sebagai delimiter karena , adalah pemisah desimal. CSV dengan delimiter koma terbuka dengan setiap baris menumpuk di kolom A. Preset Excel pada tool json-to-csv kami beralih ke ; + CRLF + UTF-8 BOM hanya dengan satu klik.
Kedua, notasi ilmiah. Excel melihat 9007199254740993 dan menampilkannya sebagai 9.00719925474E+15. Simpan bilangan bulat besar sebagai string di JSON sumber dan aktifkan BOM agar Excel menjaga sel tetap sebagai teks. Konverter kami mendeteksi bilangan bulat besar secara otomatis.
Ketiga, batas kolom praktis. Excel secara teoretis mendukung 16.384 kolom, tetapi di atas ~500 sudah sulit ditangani. Stringify sub-pohon yang berat atau lakukan pra-proyeksi dengan jq sebelum mengonversi.
Pandas: json_normalize + explode
Pola standar untuk array bersarang adalah record_path + meta dalam satu langkah:
import pandas as pd
orders = [{
"order_id": "ord-001",
"customer": {"name": "Alice", "city": "Seattle"},
"items": [{"sku": "SKU-100", "qty": 2}, {"sku": "SKU-205", "qty": 1}]
}]
df = pd.json_normalize(orders, record_path='items',
meta=['order_id', ['customer', 'name'], ['customer', 'city']], sep='_')
df.to_csv("orders.csv", index=False)
Output-nya satu baris per item dengan order_id, customer_name, dan customer_city yang berulang. Ini lebih baik daripada menjalankan explode dulu kemudian json_normalize: record_path melewati kolom objek perantara dan meta membiarkan Anda mengontrol field induk mana yang dibawa. Untuk input yang elemen array-nya berisi objek bersarang, atur max_level= untuk membatasi kedalaman.
BigQuery / Snowflake: TSV + JSON-dalam-sel
LOAD DATA di BigQuery ketat soal pengutipan CSV dan sering salah mengurai file yang berisi koma di dalam teks ber-kutip. TSV lebih aman karena tab hampir tidak pernah muncul di dalam field teks:
bq load --source_format=CSV --field_delimiter='\t' \
dataset.orders gs://bucket/orders.tsv \
order_id:STRING,customer:STRING,items:STRING
Ketika Anda memuat data bersarang sebagai JSON yang ter-Stringify dalam satu kolom, BigQuery tetap dapat menelusurinya dengan JSON_EXTRACT_SCALAR:
SELECT order_id, JSON_EXTRACT_SCALAR(items, '$[0].sku') AS first_sku
FROM dataset.orders;
Snowflake menyediakan kapabilitas sama melalui VARIANT, dengan path query seperti items:0.sku::STRING. Di kedua engine, Stringify + query path JSON mengalahkan pemerataan penuh saat array bersarang besar atau panjangnya bervariasi.
PostgreSQL COPY: RFC 4180 Ketat
COPY ... FROM ... WITH (FORMAT csv, HEADER true) adalah pembaca RFC 4180 paling ketat yang umum Anda temui. Dua perilaku yang sering menjegal.
Pertama, COPY tidak menerima UTF-8 BOM. Tanda urutan byte tersebut menjadi awalan literal pada nama kolom pertama (id alih-alih id), dan setiap query yang merujuk id gagal diam-diam. Matikan BOM untuk target Postgres.
Kedua, COPY tidak dapat mengurai data bersarang secara native. Entah ekspansi array menjadi banyak baris sebelum dimuat, atau definisikan tujuan sebagai jsonb dan lakukan stringify pada nilai bersarang:
CREATE TABLE orders (order_id text PRIMARY KEY, customer text, items jsonb);
COPY orders FROM '/tmp/orders.csv' WITH (FORMAT csv, HEADER true);
SELECT order_id, items->0->>'sku' AS first_sku FROM orders;
Untuk pipeline yang sudah berbicara JSON end-to-end, lewati CSV dan gunakan COPY ... FROM ... WITH (FORMAT text) dengan input JSON-line.
Penelusuran Payload Dunia Nyata
Penelusuran 1: Pesanan E-commerce (info pelanggan + array item)
Pesanan tipikal menggabungkan info pelanggan bersarang dengan array item berukuran variabel:
[{ "id": "ord-001",
"customer": { "name": "Alice", "address": {"city": "Seattle", "country": "US"} },
"items": [{"sku": "SKU-100", "qty": 2}, {"sku": "SKU-205", "qty": 1}] }]
Strategi yang tepat bergantung pada siapa yang membaca file. Tim Finance ingin satu baris per item untuk menghitung pendapatan per SKU; itu strategi ekspansi, menghasilkan dua baris dengan id dan customer.name berulang. Tim Operasi ingin satu baris per pesanan untuk dashboard fulfillment; itu notasi titik dengan items ter-Stringify agar array tidak meledakkan jumlah kolom. Input sama, dua output, keduanya benar untuk konsumennya masing-masing.
Tempelkan payload ke Konverter JSON ke CSV kami dan toggle Flatten versus Stringify pada opsi Nested. Contoh “Nested E-commerce Orders” memuat bentuk yang sama.
Penelusuran 2: GitHub Issues API (array labels + objek user)
Endpoint /repos/{owner}/{repo}/issues mengembalikan bentuk bersarang campuran:
[{ "id": 1001, "title": "Bug: login 404", "state": "open",
"labels": ["bug", "priority:high"], "user": {"login": "alice"} }]
user adalah objek dengan satu field berguna; labels adalah array string dengan panjang tak terbatas. Praktiknya hybrid: notasi titik untuk user (Anda hanya peduli pada user.login), dan gabungkan labels ke satu sel dengan pemisah ;:
id,title,state,labels,user.login
1001,Bug: login 404,open,bug;priority:high,alice
Tidak ada satu strategi yang sekaligus “gabungkan array ke dalam sel” dan “ratakan objek dengan titik”. Konverter kami menangani pemerataan objek secara otomatis; lakukan pra-proses pada labels dengan jq (map(.labels = (.labels | join(";")))) atau terima perilaku default array-stringify.
Penelusuran 3: MongoDB mongoexport ($oid + metadata)
mongoexport --jsonArray menghasilkan pembungkus Extended JSON:
[{ "_id": {"$oid": "6634a1b2c3d4e5f600000001"},
"email": "alice@example.com",
"metadata": { "signupDate": "2026-01-15T10:30:00Z",
"preferences": {"newsletter": true, "theme": "dark"} } }]
Pembungkus $oid menghasilkan kolom yang secara literal bernama _id.$oid, yang ditolak oleh sebagian besar engine SQL. Lakukan pra-proses dengan jq untuk membongkarnya:
mongoexport --collection=users --jsonArray | jq 'map(._id = ._id."$oid")' > users.json
Untuk blok metadata.preferences yang bersarang dalam, pilih berdasarkan konsumen. Ekspor untuk analis: ratakan semuanya dengan titik; metadata.preferences.theme enak dibaca. Round-trip pipeline: stringify metadata untuk menjaga struktur tetap utuh. Untuk pola jq lengkap yang berpasangan dengan pipeline CSV, lihat Cheat Sheet jq kami.
Penelusuran 4: Spec Pod Kubernetes (bersarang sangat dalam)
Respons kubectl get pod -o json adalah skenario terburuk untuk strategi datar. Strukturnya rutin berjalan enam level dalam (spec.template.spec.containers.0.resources.limits.memory). Pemerataan titik secara naif menghasilkan nama kolom yang melebihi 70 karakter dan output 200+ kolom. Dua strategi yang berhasil.
Lakukan pra-proyeksi dengan kubectl jsonpath. Pilih hanya field yang benar-benar Anda butuhkan:
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[0].image}{"\t"}{.status.phase}{"\n"}{end}' > pods.tsv
Stringify spec, ratakan metadata. Pertahankan metadata (name, namespace, labels) tetap datar dan stringify spec ke satu sel:
kubectl get pods -o json | jq 'map({name: .metadata.name, namespace: .metadata.namespace, spec: (.spec | tostring)})'
Lalu tempelkan ke konverter dengan mode Flatten. Kolom spec menjadi satu sel JSON; kolom metadata tetap mudah dibaca. Hindari anti-pattern kubectl get pod -o json | json-to-csv flatten tanpa pra-proyeksi. Jumlah kolomnya akan lepas kendali.
Keamanan Round-Trip: Flatten Bersifat Lossy, Stringify Lossless
Ada satu hal yang sering tidak ditegaskan di panduan lain. Notasi titik, garis bawah, array terindeks, dan ekspansi baris adalah proyeksi satu arah. Begitu Anda meratakan dengan salah satunya, JSON asli tidak dapat direkonstruksi sempurna dari CSV saja.
Contoh tandingan mudah dibangun. Kolom bernama customer.address.city ambigu antara {"customer": {"address": {"city": "..."}}} dan {"customer": {"address.city": "..."}}. Array terindeks tampak dapat dibalik, tetapi CSV tidak bisa mengatakan apakah items.0.sku seharusnya direkonstruksi menjadi array atau objek dengan key numerik. Ekspansi baris membutuhkan key group-by; tanpa order_id, Anda tidak bisa tahu baris mana yang berasal dari induk yang sama.
Hanya Stringify yang selamat dari perjalanan round-trip. Nilai bersarang dipertahankan apa adanya sebagai string JSON, sehingga konverter balik membaca sel, menguraikan isinya, dan menyisipkan kembali nilai aslinya secara utuh. Konversi dengan Stringify, simpan CSV-nya, tempelkan ke Konverter CSV ke JSON kami, aktifkan Infer types, dan Anda mendapatkan byte yang identik dengan input.
Aturan praktisnya: round-trip pipeline → Stringify. Analisis sekali pakai atau pelaporan → titik, garis bawah, atau ekspansi berdasarkan konsumen.
Menggunakan Tool Browser Kami
Konverter JSON ke CSV memaparkan dua dari lima strategi secara langsung: Flatten (menggabungkan notasi titik dan array terindeks) dan Stringify (menjaga struktur di dalam sel). Tiga lainnya (garis bawah, ekspansi baris, preset target SQL) hanya berjarak satu langkah pra-proses.
Sesi tipikal memakan lima klik:
- Validasi input dengan JSON Formatter kami agar kesalahan sintaks tidak berubah menjadi kegagalan konversi diam-diam.
- Tempel JSON ke Konverter JSON ke CSV. Konversi berjalan seketika.
- Atur Nested ke Flatten untuk key bertitik dan terindeks, atau Stringify untuk menjaga array dan objek dalam satu sel.
- Pilih preset: RFC 4180 untuk pipeline, Excel untuk spreadsheet EU, TSV untuk warehouse, Pipe untuk teks dengan banyak koma.
- Klik Swap direction dan gunakan Konverter CSV ke JSON dengan Infer types aktif untuk memverifikasi round-trip Stringify.
Semuanya berjalan di browser Anda. PII, ekspor internal, dan rahasia produksi tidak pernah meninggalkan halaman; tidak ada permintaan jaringan setelah halaman dimuat. Aman untuk data sensitif ketika mengunggah ke situs pihak ketiga bukan opsi.
Jebakan Umum
Enam mode kegagalan muncul berulang kali.
- Ledakan nama kolom. Spec Kubernetes dan thread review PR GitHub menghasilkan ratusan jalur daun. Solusi: pra-proyeksi dengan
jqataukubectl jsonpath, atau stringify sub-pohon berat sambil meratakan metadata. - Panjang array tidak cocok. Baris 1 punya 3 item, baris 2 punya 5 item. Array terindeks menghasilkan sel kosong di
items.3.skudanitems.4.skuuntuk baris 1. Solusi: beralih ke ekspansi baris. - Key indeks diperlakukan sebagai string saat dibalik. Ketika CSV-to-JSON melihat
items.0.sku,0secara teknis adalah key string. Sebagian konverter balik merekonstruksi{"0": {"sku": "A"}}alih-alih[{"sku": "A"}]. Solusi: gunakan Stringify untuk round-trip. - Key yang sudah mengandung pemisah. Event GA4 memiliki key seperti
event_params.keyyang mengandung titik literal; pemerataan dengan.menghasilkan jalur ambigu. Solusi: gunakan garis bawah, atau ubah nama key yang bermasalah. Lihat JSON5 vs JSONC untuk latar belakang tentang format JSON dengan dukungan key yang diperluas. - Tipe campuran antar level. Sebagian baris memiliki
addresssebagai objek, sebagian lain sebagainull. Pemerataan menghasilkan sel kosong di tempat objek bernilai null. Catatan skema pada konverter kami menandainya sehingga Anda dapat memverifikasi konsumen hilir. - Bilangan bulat besar terpotong oleh Excel. Long
$oid, ID snowflake Twitter, atauresourceVersionK8s melebihi rentang aman JavaScript (2^53 - 1) dan dibulatkan diam-diam. Excel kemudian menampilkannya sebagai9.00719925474E+15. Solusi: simpan ID sebagai string di JSON sumber, aktifkan BOM, dan gunakan preset Excel.
FAQ
Apa cara terbaik untuk meratakan JSON bersarang ke CSV?
Cara terbaik untuk meratakan JSON bersarang ke CSV bergantung pada konsumen hilir. Gunakan notasi titik untuk Excel atau Google Sheets. Gunakan ekspansi baris ketika Pandas atau BigQuery akan mengagregasi data. Gunakan Stringify ketika CSV harus melakukan round-trip kembali ke JSON tanpa kehilangan data. Cocokkan strategi dengan pembaca berikutnya.
Bagaimana mengonversi array JSON menjadi banyak baris CSV?
Konversi array JSON ke banyak baris CSV menggunakan strategi ekspansi: duplikasikan field induk sekali per elemen array sehingga masing-masing menjadi baris sendiri. Di Pandas, pd.json_normalize(data, record_path='items', meta=['order_id']) menyelesaikannya dalam satu panggilan. Di SQL, UNNEST(items) menghasilkan bentuk yang sama. Key induk berulang di seluruh baris hasil ekspansi.
Bisakah saya round-trip CSV kembali ke JSON bersarang asli?
Round-trip CSV kembali ke JSON bersarang asli hanya bekerja dengan mode Stringify. Notasi titik, garis bawah, array terindeks, dan ekspansi baris adalah proyeksi satu arah yang lossy; konverter balik tidak dapat merekonstruksi pohon dengan sempurna. Stringify mempertahankan array dan objek sebagai JSON di dalam satu sel, sehingga round-trip penuh menjadi identik byte ketika Infer types aktif.
Mengapa Excel menampilkan JSON yang sudah saya ratakan sebagai satu kolom panjang?
Excel menampilkan JSON yang sudah Anda ratakan sebagai satu kolom panjang ketika Anda berada di locale Eropa (Jerman, Prancis, Italia, Spanyol) di mana koma dicadangkan untuk desimal dan Excel mengharapkan semicolon sebagai delimiter. Preset Excel pada json-to-csv beralih ke ; + CRLF + UTF-8 BOM dengan satu klik.
Sebaiknya pakai notasi titik atau garis bawah untuk nama kolom?
Gunakan notasi titik ketika target adalah Excel, Google Sheets, atau Pandas; titik adalah default json_normalize dan terbaca alami. Gunakan garis bawah ketika target adalah SQL: Postgres, BigQuery, dan Snowflake menuntut pengutipan identifier yang mengandung titik, sedangkan garis bawah diterima tanpa kutip di mana pun.
Bagaimana pandas json_normalize menangani array berisi objek?
Pandas json_normalize menangani array berisi objek melalui argumen record_path dan meta. pd.json_normalize(data, record_path='items', meta=['order_id']) mengekspansi items menjadi satu baris per elemen dengan order_id berulang. Untuk objek bersarang tanpa array, pd.json_normalize(data, sep='_') yang lebih sederhana menghasilkan nama kolom dengan pemisah garis bawah seperti customer_address_city. Gunakan max_level= untuk membatasi kedalaman pada pohon yang dalam.
Berapa batas kolom saat meratakan JSON bersarang dalam?
Batas kolom saat meratakan JSON bersarang dalam adalah 16.384 di Excel dan efektif tak terbatas di CSV itu sendiri, tetapi di atas 500 kolom output sudah sulit ditangani. Spec Pod Kubernetes atau respons GraphQL mudah melampaui itu. Stringify sub-pohon berat dengan Konverter JSON ke CSV atau lakukan pra-proyeksi dengan jq atau kubectl jsonpath.
Apakah jq tool yang baik untuk meratakan JSON sebelum konversi CSV?
Ya, jq adalah tool yang tepat untuk meratakan JSON sebelum konversi CSV. Tool ini menangani pra-proyeksi (map({id, name})), pra-ekspansi (.[] | {id, item: .items[]}), dan normalisasi bentuk dalam satu baris. Pipeline jq berjalan sebelum tahap CSV dan mengontrol persis field mana yang sampai ke konverter. Lihat Cheat Sheet jq kami untuk pola-polanya.
Kesimpulan
Lima poin utama:
- JSON-ke-CSV adalah masalah geometri, bukan masalah sintaks. Pohon tidak bisa muat di grid tanpa memilih bagaimana cabang-cabangnya runtuh.
- Lima strategi mencakup seluruh ranah praktis (titik, garis bawah, array terindeks, ekspansi baris, Stringify). Pilih berdasarkan konsumen.
- Stringify adalah satu-satunya jalur tanpa kehilangan data. Gunakan untuk round-trip pipeline.
- Excel-EU dan BigQuery memiliki preset bukan tanpa alasan. Manfaatkan.
- Payload nyata (mongoexport, spec Kubernetes, respons GitHub) biasanya butuh langkah pra-proyeksi
jqataukubectl jsonpathterlebih dahulu.
Coba payload Anda sendiri di Konverter JSON ke CSV. Berjalan lokal, menangani kelima strategi, round-trip lossless dengan Stringify. Tanpa upload, tanpa pendaftaran, data tidak meninggalkan halaman.