How to normalize json keys to snake_case database columns
- Step 1Confirm your column naming — Run
SELECT column_name FROM information_schema.columns WHERE table_name = 'your_table'. If the columns are snake_case (the common case), snake_case is your target. If they are camelCase quoted identifiers, target camelCase instead. - Step 2Drop the JSON record batch — Drag the JSON array of records onto the dropzone. The tool reads a file (not pasted text); free tier accepts up to 2 MB.
- Step 3Select snake_case — Click snake_case in the Target case style row. Every key in every record will be normalized to snake_case regardless of its source casing.
- Step 4Keep Deep rename on for embedded JSON — Leave Deep rename checked if records contain nested objects that map to JSONB columns. Uncheck it if only the flat top-level fields are columns and nested blobs should stay verbatim.
- Step 5Run and check the renamed count — Click Rename Keys. Compare the renamed count to your expectation; a surprisingly low count can mean keys were already snake_case, and a missing field can mean a casing collision dropped it.
- Step 6Feed the output to your ORM — Copy or download the result and pass it to your bulk insert, e.g.
await prisma.users.createMany({ data: renamed }). The keys now match the column names exactly.
API field to database column (snake_case target)
How common API field names normalize when you select snake_case. These are the renames the tool performs automatically — same word, different case. Renames where the word itself differs are not in scope.
| API field (source) | snake_case column (output) | Notes |
|---|---|---|
firstName | first_name | Standard case boundary split |
createdAt | created_at | Common timestamp column |
orderID | order_id | Trailing acronym lowercased to id |
apiKey | api_key | Multi-letter acronym splits before next word |
isActive | is_active | Boolean flag column |
metaData | meta_data | If your column is metadata (one word), this won't match — rename in code |
Free vs Pro limits for record batches
The JSON-family tier limits that govern how large a record batch you can process. The limit is on file bytes, not record count.
| Tier | Max JSON file size | Batch files |
|---|---|---|
| Free | 2 MB | 1 |
| Pro | 100 MB | 10 |
| Pro + Media | 500 MB | 50 |
| Developer | 5 GB | unlimited |
Cookbook
Before/after pairs from real database-prep workflows. Record values are illustrative; the point is the key-to-column normalization.
camelCase records to snake_case for Postgres bulk insert
ExampleA JS API gives camelCase records; the Postgres table uses snake_case. Pick snake_case, Deep rename on.
Input:
[
{ "firstName": "Sue", "createdAt": "2026-01-01" },
{ "firstName": "Jon", "createdAt": "2026-01-02" }
]
Target: snake_case
Output:
[
{ "first_name": "Sue", "created_at": "2026-01-01" },
{ "first_name": "Jon", "created_at": "2026-01-02" }
]Embedded JSONB column kept verbatim
ExampleIf a nested object is itself a JSONB column value, uncheck Deep rename so its keys aren't rewritten.
Input:
{ "orderId": 9, "shippingMeta": { "carrierCode": "UPS" } }
Target: snake_case, Deep rename OFF
Output:
{ "order_id": 9, "shipping_meta": { "carrierCode": "UPS" } }
(shipping_meta is the column; its inner carrierCode stays as the app wrote it.)Casing collision would drop a column value
ExampleTwo source keys that normalize to the same column name collide — JSON keeps only the last.
Input:
{ "userId": 1, "user_id": 2 }
Target: snake_case
Output:
{ "user_id": 2 }
The value 1 is silently dropped. Reconcile the source before inserting.id stays present — exclude it separately for SERIAL columns
ExampleThe renamer does not drop fields; if your id column is auto-increment, strip id with the key filter, then rename.
After rename (snake_case):
[ { "id": 101, "first_name": "Sue" } ]
For a SERIAL id column, remove id first via json-key-filter,
then run the renamer so the batch lets Postgres assign IDs:
[ { "first_name": "Sue" } ]Generate the SQL after renaming
ExampleOnce keys match columns, hand the array to a JSON-to-SQL converter to emit INSERT statements.
Renamed array (keys = columns):
[ { "first_name": "Sue", "created_at": "2026-01-01" } ]
Then json-to-sql produces:
INSERT INTO users (first_name, created_at)
VALUES ('Sue', '2026-01-01');Errors and edge cases
Real errors and silent failures sourced from each platform's own documentation. Match the wording to the row, fix what the row says to fix.
Two API fields map to the same column
Silent overwriteuserId and user_id both become user_id; JSON keeps the last value and drops the first, with no error. This can silently corrupt a record before it ever reaches the database. De-duplicate source casing first, or prune one key with json-key-filter.
Column is a single word the tool splits
Mismatch riskIf your column is metadata (one word) but the source key is metaData, the tool produces meta_data, which will not match the column and the insert will fail on an unknown column. The tool can only normalize case — it cannot merge words. Rename meta_data to metadata in code after running.
Auto-increment id column
Manual stepThe renamer never removes fields, so an incoming id stays in the record and a SERIAL/AUTO_INCREMENT column may reject or override it. Strip id first with json-key-filter, then rename.
Type casting is not performed
By designOnly keys change. A string "42" that should be an integer column stays a string. Cast types in your ORM or a post-rename map; this tool will not coerce values.
Nested object is a JSONB column
Use Deep OFFIf a nested object is stored verbatim in a JSONB column, deep-renaming its inner keys may break round-tripping with the application. Uncheck Deep rename so only the top-level (column-level) keys are normalized.
Top-level is an array of objects
SupportedA record batch as a JSON array is handled element by element — exactly the shape ORMs want for bulk-create.
Quoted camelCase identifiers in Postgres
Target camelCaseIf your schema uses quoted camelCase column names rather than snake_case, select camelCase instead so the keys match the quoted identifiers, not the folded default.
File over 2 MB on free tier
Blocked on freeLarge batches exceed the 2 MB free JSON limit and are blocked with an upgrade prompt. Split the batch or upgrade to Pro (100 MB).
Invalid JSON
Parse errorA malformed export (trailing comma, NDJSON instead of a JSON array) fails JSON.parse and nothing is produced. Convert NDJSON to a proper array first, then rename.
Frequently asked questions
Can I map firstName to a totally different column like given_name?
No. This tool only changes case — firstName can become first_name, but it cannot become given_name because the words differ. For word-level renames, do that step in your ETL/ORM code, or remove unmatched keys with json-key-filter and supply them separately.
Does it handle every record in an array at once?
Yes. Drop a JSON array of records and every object is normalized in the same pass, producing a consistently-keyed batch ready for bulk-create.
Should I rename or remove the id field?
If your id column is auto-increment, remove the source id with json-key-filter before renaming so the database assigns new IDs. Keep id only when you are deliberately seeding specific values.
Can it cast string numbers to integers for numeric columns?
No — it only rewrites keys, never values. Do type casting after renaming, e.g. a map over the array that parses the numeric and date fields.
My nested object is a JSONB column — will it mangle the inner keys?
By default yes, because Deep rename recurses. Uncheck Deep rename to normalize only the top-level column keys and leave the JSONB payload exactly as the application wrote it.
How does it handle acronyms in column names?
orderID → order_id, apiKey → api_key, userURL → user_url. A trailing acronym like ID or URL is lowercased as one word; an acronym that precedes another capitalized word splits at that boundary.
What if two source keys collide on the same column?
JSON cannot hold duplicate keys, so the last value written wins and the other is dropped silently. This is a real data-loss risk — reconcile mixed-casing source keys before inserting.
Can I generate the INSERT statements here too?
Not in this tool. After renaming so keys equal columns, run the output through json-to-sql, which emits INSERT statements and supports options like excludeColumns and ON CONFLICT handling.
What's the size limit for a batch?
2 MB per file on free; 100 MB on Pro; more on higher tiers. The constraint is bytes, not row count.
Does selecting snake_case re-format the whole file?
Yes — the output is re-serialized with 2-space indentation, so even keys already in snake_case come out consistently formatted.
Is my customer data uploaded?
No. Parsing and renaming run entirely in your browser. Records with PII never reach JAD Apps servers.
Can I convert keys to camelCase for a Mongo/NoSQL store instead?
Yes — select camelCase. The same normalization applies; pick whichever case your target store expects.
Privacy first
Conversion runs locally in your browser. No file is uploaded — only metadata counters are saved for signed-in dashboard stats.