JSON to SQL converter
Turn a JSON array of objects into CREATE TABLE plus INSERT statements. Nested objects and arrays are stored as JSON text; every other key gets an inferred column type.
JSON already has types — a number is a number and true is a boolean — which makes it a better starting point for SQL than a CSV. What it does not have is a fixed shape: one object in an array can carry a key the next one lacks, and any value can itself be an object or an array. This page resolves both. It takes the union of every key across every object, in first-seen order, so the table has a column for each; it infers a database type per column from the real values; and it stores anything nested as JSON text rather than pretending a table can hold a tree. The output is a CREATE TABLE plus batched INSERTs in MySQL, PostgreSQL or SQLite syntax.
Key facts about JSON to SQL converter
| Accepted shapes | An array of objects, a single object, an object with an array of objects inside it, or NDJSON/JSON Lines with one object per line |
|---|---|
| Column discovery | The union of every key across every object, in the order the keys are first seen — a key missing from some objects becomes NULL there |
| Nested values | An object or array value is JSON.stringified into a text column; it is not flattened into extra columns and not dropped |
| Native JSON types | A real JSON number becomes INT or DOUBLE, a real true/false becomes the dialect's boolean, and null becomes NULL — no string parsing needed |
| Dialects | MySQL (backtick identifiers), PostgreSQL and SQLite (double-quoted) — with the right type names and boolean literals for each |
| Timestamps | An ISO string like 2026-01-02T09:30:00Z is recognised as a timestamp column: DATETIME on MySQL, TIMESTAMP on PostgreSQL, TEXT on SQLite |
| Big integers | Values past 2,147,483,647 promote the column to BIGINT instead of overflowing INT |
| Escaping | Single quotes are doubled in every dialect; MySQL additionally gets its backslashes doubled, which matters for stringified JSON full of them |
| Batching | 1, 50, 100 or 500 rows per INSERT statement |
| NOT NULL | Only on columns where every object supplies a value — a key that is sometimes absent is left nullable |
| Key sanitising | A key like "order total" or "2026-total" becomes a valid identifier, and every column name stays editable before export |
| Input ceiling | 10 MB of JSON text, held in memory along with the generated SQL |
What happens to your file
The JSON is parsed by the browser's own JSON.parse in this tab, the SQL is built as a string in page memory, and the download is a Blob handed to a temporary object URL. No database connection exists anywhere in this page — it writes statements, it never runs them — and no API receives your objects. That is worth stating precisely because JSON exports are often API responses containing customer records: nothing here transmits them, nothing is written to localStorage, and reloading the page clears everything. You can disconnect from the network after the page has loaded and every part of the conversion still works.
About this tool
- 1
Paste or load the JSON
An array of objects is the normal case. A single object becomes a one-row table, an object wrapping an array is unwrapped, and JSON Lines is detected automatically.
- 2
Pick the dialect
MySQL, PostgreSQL or SQLite. This decides identifier quoting, type names, boolean literals and transaction keywords, so choose it before reviewing the types.
- 3
Check the column list
Every key found across every object is listed with the type inferred for it. Nested objects and arrays show as text columns — that is intentional, and the value stored is the JSON for that subtree.
- 4
Rename what needs renaming
Keys with spaces, dots or leading digits are sanitised into valid identifiers. Each name is an input field, so you can match an existing schema exactly.
- 5
Set the statement options
CREATE TABLE and IF NOT EXISTS are on by default. Add an auto-increment key when your objects have no id, DROP TABLE for a clean re-run, and a transaction wrap so a bad row rolls the whole load back.
- 6
Export
Copy the SQL into your client or download the .sql and run it with mysql, psql or sqlite3. Batch size 100 is a good default.
| Input | .json, .ndjson, .jsonl or .txt, or JSON pasted into the box; up to 10 MB |
|---|---|
| Output | A .sql text file, or the same text copied to the clipboard |
| Parser | The browser's native JSON.parse, with a per-line fallback so JSON Lines works without a separate mode |
| Statement shape | CREATE TABLE [IF NOT EXISTS], optional DROP TABLE IF EXISTS first, then INSERT INTO … VALUES with one tuple per object |
| Transaction wrapping | Optional — START TRANSACTION/COMMIT on MySQL, BEGIN/COMMIT on PostgreSQL and SQLite |
| Preview | The first 20,000 characters render in the page; the download and clipboard carry all of it |
| Error handling | Invalid JSON is reported with the parser's own message and position rather than silently producing an empty table |
| Browser support | Chrome, Edge, Firefox and Safari; the copy button needs a secure context |
- If your API wraps results in { "data": [ … ] }, paste the whole response — the array inside is found and used.
- Nested arrays that you actually want as rows belong in a second table; extract them in a script first, then convert each level separately here.
- JSON numbers keep their type, so an id field arrives as INT without the leading-zero ambiguity a CSV has.
- A key that appears in only some objects becomes a nullable column — check the NOT NULL column in the type table if you expected a constraint.
- Stringified JSON in a MySQL text column is exactly where backslash escaping goes wrong in hand-written SQL; it is doubled here for MySQL only, as that engine requires.
- For repeated imports, keep DROP TABLE on and the transaction wrap on: the load is then idempotent and all-or-nothing.
- Array, single object, wrapped array and NDJSON input
- Union-of-keys column discovery across ragged objects
- Nested objects and arrays preserved as JSON text
- MySQL, PostgreSQL and SQLite with dialect-correct types and escaping
- Batched multi-row INSERTs with optional transaction wrapping
- Editable column names and a live SQL preview
- Loading an API response into a database so you can query it with SQL instead of scripting over the JSON.
- Seeding a development or test database from a fixture file that already lives in the repo.
- Migrating a document-store export into a relational schema, one collection at a time.
- Turning a webhook log in JSON Lines into a table for analysis.
- Producing a migration file that a reviewer can read as SQL rather than as a data blob.
- Getting a quick SQLite table out of a JSON dump for local exploration.
Related tools
View allWorks well with this5
Other JSON tools12
Updated