Paste JSON data
Add a JSON array, object, API response, or seed data export. Use the sample button to test nested fields and arrays.
Convert JSON arrays, objects, and API responses into SQL CREATE TABLE schemas and INSERT statements in one click. Choose PostgreSQL, MySQL, or SQLite, flatten nested JSON, infer column types, and download a ready to use SQL file. Everything runs locally in your browser.
Generating SQL from JSON is really two jobs. The first is inferring a schema: scanning every record to work out which columns exist and what type each one should be. The second is serialising the values into INSERT statements with correct quoting and escaping.
The schema is inferred from the union of keys across all records, not just the first one, because JSON arrays are frequently ragged. A key that appears in only some records still needs a column, and the records that lack it get NULL. If a key holds a number in one record and a string in another, the widening rule applies and the column becomes text, since text can hold anything.
An orders array and the DDL plus DML it generates.
JSON input
SQL output
The apostrophe in the customer name is escaped by doubling it, which is the SQL standard mechanism. The null stays a real NULL rather than the four character string.
| JSON type | Typical SQL type | Notes |
|---|---|---|
| String, short | VARCHAR(255) | Length chosen from the longest observed value, rounded up |
| String, long or unbounded | TEXT | Anything over a few hundred characters |
| Integer within 32 bits | INTEGER | Safe for ids and counts |
| Integer beyond 32 bits | BIGINT | Timestamps in milliseconds land here |
| Float, money-like | DECIMAL(12,2) | Never use a binary float for currency |
| Float, scientific | DOUBLE PRECISION | Measurements and ratios |
| Boolean | BOOLEAN or TINYINT(1) | MySQL has no true boolean type |
| Null only, no other values | TEXT NULL | Nothing to infer from, widen to text |
| ISO date string | DATE or TIMESTAMP | Only if you opt into date detection |
| Object | JSON, JSONB, or a child table | Depends on how you will query it |
| Array | JSON, JSONB, or a join table | Same decision, see normalisation below |
Inferred lengths are a starting point, not a contract. If your sample happens to contain no name longer than forty characters, a VARCHAR sized to that sample will reject real data later. Widen anything that a user can type into.
| Feature | MySQL | PostgreSQL | SQLite |
|---|---|---|---|
| Identifier quoting | Backticks | Double quotes | Either |
| Auto increment key | AUTO_INCREMENT | SERIAL or IDENTITY | INTEGER PRIMARY KEY |
| Boolean | TINYINT(1), 0 and 1 | Native BOOLEAN, TRUE and FALSE | Stored as 0 and 1 |
| JSON column | JSON | JSON and JSONB, JSONB preferred | TEXT with JSON functions |
| Text type | VARCHAR or TEXT | TEXT, no length penalty | TEXT, types are advisory |
| Multi-row insert | Supported | Supported | Supported since 3.7.11 |
| Upsert | ON DUPLICATE KEY UPDATE | ON CONFLICT DO UPDATE | ON CONFLICT DO UPDATE |
PostgreSQL folds unquoted identifiers to lower case while MySQL on Linux is case sensitive for table names but not column names. The simplest way to avoid ever thinking about this is to generate snake_case identifiers and never quote them.
Relational tables are flat, so nested JSON forces a modelling decision. There are three options and the right one depends entirely on how you intend to query the data.
| Strategy | Result | Good when | Cost |
|---|---|---|---|
| Flatten with dot or underscore paths | address_city, address_postcode columns | Nesting is shallow and fixed | Column explosion if the shape varies |
| Store as a JSON column | One address column holding the object | Shape varies or you rarely filter on it | Indexing and joining are awkward |
| Normalise into a child table | An addresses table with a foreign key | You query, join, or aggregate on it | More work up front, more joins later |
Arrays of scalars can live in a JSON column comfortably. Arrays of objects almost always want their own table, because a line items array inside an orders row is a one to many relationship pretending not to be one. Generated SQL will usually take the JSON column route since it is the only option that never loses data, and promoting it to a proper child table is a deliberate follow up step.
Generated statements are for schema bootstrapping and seeding: creating a table from a sample payload, loading fixtures into a development database, or getting a prototype moving. That is a safe use because you control the input and you can read the output before running it.
String concatenation is never acceptable in application code. Building a query by interpolating values into a string is the definition of a SQL injection vulnerability, and escaping by hand does not save you: encodings, multi-byte characters, and dialect specific escape modes all provide ways around a naive escaper.
Never versus always
Two more habits worth keeping. Review generated DDL before you run it, since inferred types and lengths reflect one sample rather than your real domain. And add the things inference cannot see: primary keys, foreign keys, unique constraints, NOT NULL, and the indexes your queries will actually need.
Getting data into a database is one step in a longer pipeline. See the full converter collection for JSON to CSV when your loader prefers a bulk import file, JSON Schema to validate payloads before they ever reach the database, and JSON to TypeScript to type the rows in your application layer.
Add a JSON array, object, API response, or seed data export. Use the sample button to test nested fields and arrays.
Set table name, choose PostgreSQL, MySQL, or SQLite, then toggle schema generation, nested flattening, and identifier quoting.
Generate SQL live as you type. Copy it into your SQL client or download a .sql file for imports, seeds, and migration drafts.
Turn JSON exports into practical SQL for local databases, demos, test fixtures, admin imports, and migration drafts without sending sample records anywhere.
Data stays in your browser. No uploads, server logs, or database payload storage.
Generate CREATE TABLE and INSERT statements immediately from JSON input.
PostgreSQL, MySQL, and SQLite options tune booleans, JSON types, and identifiers.
Flatten nested keys into columns or preserve objects and arrays as JSON values.
Parse common INSERT statements back into clean JSON for inspection or reuse.
Copy SQL or download a ready to use file for imports, seeds, and drafts.
Need to go the other direction? The SQL to JSON tab converts common INSERT INTO statements back to structured JSON arrays. Paste your SQL INSERT statements and get clean JSON output for re-importing, testing, or working with your data in JavaScript, Python, or any other language.