Skip to main content

json-to-multicsv

Split a JSON file with hierarchical data into multiple CSV files.

A Python rewrite of jsnell/json-to-multicsv. See Juho Snellman's 2016 blog post for motivation and design.

Installation

pip install json-to-multicsv

Usage

$ json-to-multicsv --help
Usage: json-to-multicsv [OPTIONS]

  Split a JSON file with hierarchical data to multiple CSV files.

Options:
  --file FILENAME  JSON input file (default: stdin)
  --path TEXT      pathspec:handler[:name[:key_name]]
  --table TEXT     Top-level table name
  --no-prefix      Use only the last component of the table name for output
                   filenames.
  --help           Show this message and exit.

Examples

Nested objects and arrays

Given this input:

{
    "item 1": {
        "title": "The First Item",
        "genres": ["sci-fi", "adventure"],
        "rating": {
            "mean": 9.5,
            "votes": 190
        }
    },
    "item 2": {
        "title": "The Second Item",
        "genres": ["history", "economics"],
        "rating": {
            "mean": 7.4,
            "votes": 865
        },
        "sales": [
            { "count": 76, "country": "us" },
            { "count": 13, "country": "de" },
            { "count": 4, "country": "fi" }
        ]
    }
}
json-to-multicsv --file input.json \
    --path '/:table:item' \
    --path '/*/rating:column' \
    --path '/*/sales:table:sales' \
    --path '/*/genres:table:genres'

Produces three CSV files, joinable on the *._key columns:

item.csv:

item._key,rating.mean,rating.votes,title
item 1,9.5,190,The First Item
item 2,7.4,865,The Second Item

item.genres.csv:

item._key,item.genres._key,genres
item 1,0,sci-fi
item 1,1,adventure
item 2,0,history
item 2,1,economics

item.sales.csv:

item._key,item.sales._key,count,country
item 2,0,76,us
item 2,1,13,de
item 2,2,4,fi

Row handler, custom key names, and ignore

When the top-level JSON value is a single object (not a collection), use /:row with --table to name the output table. Custom key column names can be set with an extra :KEY_NAME argument on table handlers. Use :ignore to skip parts of the data.

{
    "name": "Summer Championship",
    "year": 2024,
    "games": {
        "game-1": {
            "home": "Eagles",
            "away": "Hawks",
            "score": { "home": 3, "away": 1 }
        },
        "game-2": {
            "home": "Bears",
            "away": "Lions",
            "score": { "home": 2, "away": 2 }
        }
    },
    "sponsors": ["Acme Corp", "Globex"]
}
json-to-multicsv --file tournament.json \
    --path '/:row' \
    --path '/games:table:game:gameId' \
    --path '/games/*/score:column' \
    --path '/sponsors:ignore' \
    --table main

main.csv:

name,year
Summer Championship,2024

main.game.csv:

gameId,away,home,score.away,score.home
game-1,Hawks,Eagles,1,3
game-2,Lions,Bears,2,2

Note that gameId replaces the default game._key column name, and sponsors are omitted entirely.

Top-level array

When the input is a JSON array, a single table handler at the root is all you need:

[
    {"title": "Dune", "author": "Frank Herbert", "year": 1965},
    {"title": "Neuromancer", "author": "William Gibson", "year": 1984},
    {"title": "Snow Crash", "author": "Neal Stephenson", "year": 1992}
]
json-to-multicsv --file books.json --path '/:table:book'

book.csv:

book._key,author,title,year
0,Frank Herbert,Dune,1965
1,William Gibson,Neuromancer,1984
2,Neal Stephenson,Snow Crash,1992

Options

--file INPUT

Read JSON input from a file. Defaults to stdin.

--path PATHSPEC:table:NAME[:KEY_NAME]

Values matching the pathspec open a new table with the given name. The value should be an object or array. For objects, each field produces a row, with the field name stored in the NAME._key column. For arrays, each element produces a row, with the 0-based index stored in the NAME._key column.

When tables are nested, key columns from all outer tables are included in inner tables.

An optional key name can be provided to customize the key column name (e.g., /:table:item:itemId produces an itemId column instead of item._key).

--path PATHSPEC:column

Values matching the pathspec are emitted as columns in the current table's row. If the value is a scalar, it becomes a single column. If the value is an object, its fields are flattened into multiple columns with dotted names.

--path PATHSPEC:row

Values matching the pathspec are emitted as new rows in the current table. The value must be an object. This is generally only useful for the top-level JSON value, combined with --table.

--path PATHSPEC:ignore

Values matching the pathspec (and all their children) are skipped.

--table NAME

Name the top-level table. Use this with a row handler on the root element.

--no-prefix

Use only the last component of the table name for output filenames. For example, item.sales.csv becomes sales.csv.

Paths and pathspecs

The path to a JSON value is determined by:

  • The root element's path is /
  • For values inside an object: parent path + / + field name
  • For values inside an array: parent path + / + 0-based index

In a pathspec, any path component can be replaced with *, which matches any single component. For example, /a/*/c matches /a/b/c but not /a/b/b/c.

License

MIT. Based on json-to-multicsv by Juho Snellman.

Metadata

Release files for json-to-multicsv 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for json-to-multicsv 0.1.2
File Size Uploaded Provenance Actions
json_to_multicsv-0.1.2.tar.gz 16.1 kB With provenance Details for json_to_multicsv-0.1.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for json-to-multicsv 0.1.2
File Interpreter ABI Platform Actions
json_to_multicsv-0.1.2-py3-none-any.whl Python 3 none any Details for json_to_multicsv-0.1.2-py3-none-any.whl

Total release size: 26.0 kB

Release files / json_to_multicsv-0.1.2.tar.gz

Download URL json_to_multicsv-0.1.2.tar.gz
Size 16.1 kB
Tags Source
SHA-256 checksum
How to use checksums
cf1757854efd6dd89c92e05a8028f081eb94eecc3fe3b9d2bf4e27b8c4aa738e
BLAKE2b-256 checksum
How to use checksums
d6fdee330b38050fe13f70598a6984efa432de06465c597ad887901e547a14fa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 18, 2026.

Transparency log

Release files / json_to_multicsv-0.1.2-py3-none-any.whl

Download URL json_to_multicsv-0.1.2-py3-none-any.whl
Size 9.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
47eab4ee0b56ab70f3da6d4c553ea4f45269a12ff9c76164d5f0623d03e604a2
BLAKE2b-256 checksum
How to use checksums
899c9221ff7776bf02b749625206d7cb931cba4865c265bdf912852a534fec9e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 18, 2026.

Transparency log

Security for json-to-multicsv 0.1.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for json_to_multicsv-0.1.2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 18, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page