# SQL Dump to SQLite: MySQL and Postgres Rows, Unchanged

SQL Dump to SQLite: MySQL and Postgres Rows, Unchanged is a tested SKILL.md that converts a MySQL or PostgreSQL dump (CREATE TABLE, INSERT rows, COPY blocks) into SQL that SQLite, Cloudflare D1 and Turso execute, with every value in every row unchanged, and answers with the SQL only, no code fence; an agent buys it once for $0.03 over x402.

- Page: https://aiskills402.com/skills/sql-dump-to-sqlite
- Category: Code & Engineering (https://aiskills402.com/categories/code)
- Price: $0.03 once, USD-priced, paid in USDC on Base over x402. Price as loaded on this page. The 402 response your agent receives is authoritative.
- Version: 1.0.0
- Card (JSON): https://api.aiskills402.com/v1/skills/sql-dump-to-sqlite

## Use it when

Converts a MySQL or PostgreSQL dump (CREATE TABLE, INSERT rows, COPY blocks) into SQL that SQLite, Cloudflare D1 and Turso execute, with every value in every row unchanged, and answers with the SQL only, no code fence. Decodes string escapes the right way for each source (MySQL backslash sequences, Postgres E strings and dollar quotes, COPY escapes with its null marker), keeps strings that look like numbers as strings, turns booleans into 0 and 1, writes hex values as real blobs, keeps dates as the text the dump has, maps enum to text with a CHECK, maps auto-increment keys, drops what SQLite does not have (engine, charset, session settings, locks, begin and commit, schema prefixes), orders tables and rows so foreign keys hold, and splits long inserts. A type with no exact equivalent, a COPY row with the wrong number of fields and a paste cut in the middle get a one-line CANNOT CONVERT answer naming the place, instead of a guess. Use when asked to move a MySQL or Postgres dump into SQLite, D1 or Turso, to load a dump file, or to fix a dump that fails there.

## Not for

Designing a new schema, tuning queries, running the load or reading your live database. It converts the dump you paste, so a table you did not paste is unknown. Spatial types, arrays, ranges, a NUL character in a string, a COPY row with the wrong number of fields and a paste cut in the middle get a CANNOT CONVERT line instead of a guess. Stored procedures, views and triggers are not converted.

## Tested, honestly

Tested 2026-10-08.

- Strong model (claude-sonnet-5-5 (Claude Code alias "sonnet")): Right on all 24 dumps, read by hand: every converted dump ran in SQLite and returned the same values as the source, with MySQL backticks, AUTO_INCREMENT keys, unsigned and enum columns, escaped quotes, percent and underscore in strings, Postgres booleans written as t and f, exact numerics, sequences, COPY blocks and timestamps carried over; no BEGIN or COMMIT left in a file meant for D1; and a refusal where SQLite cannot hold the column, such as a spatial POINT, instead of a silent change of type.
- Weak model (claude-haiku-5-5 (Claude Code alias "haiku")): Right on 23 of 24 dumps, read by hand, but it missed one: in a Postgres dump it turned one boolean written as t into 0 instead of 1.

Note: Twenty-four MySQL and Postgres dumps written by us (17 with a trap, 7 plain). Each answer is run in a fresh SQLite database by our script, then the same queries are compared with the expected rows, types included; statements D1 rejects (BEGIN, COMMIT, transactions) are refused by pattern, and a dump with a type SQLite cannot hold must be refused in words. The D1 facts (no BEGIN TRANSACTION in a migration file, measured on a cloud database on 2026-10-08) are owner-measured; SQLite behaviour was checked by running every expected answer. No check was widened. One run per model and dump.

### With and without the skill

Tested 2026-10-08.

- Dumps converted or refused right (24 dumps): Sonnet 24/24 with, 22/24 without; Haiku 23/24 with, 21/24 without.

Same request on both sides, a fence removed first. Read by hand, Sonnet without the skill already carried over backticks, escapes, enums, booleans, numerics and COPY blocks with every value intact. It missed two: it kept a BEGIN in a file meant for D1, which D1 refuses, and it turned a spatial POINT column into plain text without a word instead of refusing. Haiku without the skill missed three: escaped percent and underscore, the key and BEGIN, and an exact numeric.

Same cases and the same checks with and without the skill. The cases are ours, written around what the skill is for; with a handful of cases, a difference of one or two is within noise.

Full summary: https://aiskills402.com/skills/sql-dump-to-sqlite/tests

## Example

### English (claude-sonnet-5-5)

Before:

> -- MySQL dump 10.13  Distrib 8.0.36, for Linux (x86_64) /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET NAMES utf8mb4 */; CREATE TABLE `people` (   `id` int(11) NOT NULL AUTO_INCREMENT,   `name` varchar(60) NOT NULL,   `note` text,   PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;…

After:

> CREATE TABLE "people" (   "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,   "name" TEXT NOT NULL,   "note" TEXT ); INSERT INTO "people" ("id", "name", "note") VALUES (1, 'O''Brien', 'He said "hi"'), (2, 'Ann', 'line one' || char(10) || 'line two'), (3, 'Bo', 'C:\temp\new'), (4, 'Cy', 'tab' || char(9) || 'here');

### Bulgarian (claude-sonnet-5-5)

Before:

> -- Дъмп на таблицата с клиенти CREATE TABLE `clients` (`id` int NOT NULL, `name` varchar(80) NOT NULL, `city` varchar(40) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; INSERT INTO `clients` VALUES (1,'Иван Петров','гр. София'),(2,'Мария \'Мими\' Георгиева','Пловдив'),(3,'Стоян Димитров',NULL);

After:

> CREATE TABLE clients (   id INTEGER NOT NULL PRIMARY KEY,   name TEXT NOT NULL,   city TEXT DEFAULT NULL ); INSERT INTO clients (id, name, city) VALUES (1, 'Иван Петров', 'гр. София'), (2, 'Мария ''Мими'' Георгиева', 'Пловдив'), (3, 'Стоян Димитров', NULL);

## What is in the file

- The answer
- What goes, what stays
- Strings
- Types
- Keys and order
- COPY blocks (Postgres)
- NULL and empty
- When to refuse
- Work in this order
- Short examples

## Languages

Any language

## How to buy

Agent (HTTP):

1. GET https://api.aiskills402.com/v1/skills/sql-dump-to-sqlite/file without a payment header. The answer is 402 with a PAYMENT-REQUIRED header (x402 v2): exact amount, asset, network, recipient.
2. Sign `accepts[0]` with an x402 client (for example @x402/core + @x402/evm).
3. Repeat the GET with the signature in the PAYMENT-SIGNATURE header. The answer is 200 with the file, its sha256 and a re-download token.

Agent (MCP): https://mcp.aiskills402.com/mcp — free tools search_skills, get_skill, redownload_skill. Buying itself is over HTTP.

Full flow: https://aiskills402.com/docs

## The file

- Version: 1.0.0
- Size: 12.4 KB (12650 bytes)
- SHA-256: 43634b3ed3fa1390fc44c1b54547717892b778c1fa2ed34b921ede7ecf12414a
- Updated: 2026-10-08
- New versions are free through your re-download token.

## Versions

### 1.0.0 (2026-10-08)

First release (draft, not yet measured): converts a MySQL or PostgreSQL dump piece (CREATE TABLE, INSERT rows, COPY blocks) into SQL that SQLite, Cloudflare D1 and Turso execute, SQL only, every value unchanged, with a one-line CANNOT CONVERT refusal for a type with no exact equivalent, a COPY row with the wrong number of fields and a paste that stops in the middle.

Facts re-checked on 2026-10-08 (free, read-only, no account needed): - SQLite: a hexadecimal literal 0x... is an integer, a blob is X'...' (SQLite expression documentation, fetched); node:sqlite 3.53.0 locally: a quoted 20-digit decimal stored in a NUMERIC column becomes a floating point number (measured by the case control), so only the TEXT column type protects the digits. - PostgreSQL: COPY text format (null marker backslash-N, backslash sequences, end-of-data line, error on a wrong field count), escape strings and dollar quoting (documentation, fetched). - Cloudflare D1 limits: 100 KB per SQL statement, 100 bound parameters (limits page, fetched). - MariaDB string literal page fetched (backslash escape table, unknown escapes ignored); the MySQL manual page returned 403 to the fetch, so the MySQL rules rest on that page plus the MySQL manual from memory. Backslash-percent and backslash-underscore keeping their backslash is the MySQL rule and is NOT re-checked here. - BEGIN refused by D1 with code 7500 and foreign_keys = OFF being a no-op in a D1 migration are owner-measured on 2026-10-08 (d1-migrations note), not re-checked.

Tests: 24 cases (15 traps, 3 refusals, 6 controls), `test/control.mjs` makes zero model calls. Model results are not in yet; price and the "Sonnet got N of M" sentence in the listing are written after the baseline.

## License

Perpetual, non-exclusive; use and modify for yourself incl. paid work; no resale or republishing. Holder: Georgi Kalchev, aiskills402.com. Terms: https://aiskills402.com/docs#license

## FAQ

### Backticks, booleans, escapes: what does a plain conversion break?

The quiet ones. MySQL writes a quote inside a string as backslash and quote, which SQLite reads as a string that ends early. A MySQL backslash before a percent sign keeps the backslash, a plain Postgres string never decodes its backslashes, a COPY field that is only backslash and N is NULL while an empty field is an empty string, a hex literal written 0x is an integer in SQLite and not bytes, and a code like 007 must stay text. It also puts parent tables before child tables, because D1 checks foreign keys while the file runs and a dump lists tables alphabetically.

### What happens when the dump has something SQLite cannot hold?

What comes back is one short line opening with CANNOT CONVERT and names the table and the column or row, for example a spatial point column or a COPY row that has two fields where the list names three. A table loaded halfway is worse than none, so the skill does not convert the fine part and skip the rest. Send the dump again without that column and the SQL follows. A value that is only unusual, such as a zero date or an empty string, is not a reason to refuse: it is carried over as written.

### Does it change any value?

Only one kind, and it says so in a comment: boolean values become 0 and 1, because a text f is not false in SQLite. Dates stay the text the dump has, numbers stay as written, and a number with more digits than a floating point value can carry goes into a TEXT column quoted, so no digit is rounded.

### Does it help Claude Sonnet?

Two points that bite on D1 make the difference. Twenty-four dumps were converted by both Claude models, loaded and unloaded, and each answer was executed in SQLite. On its own Sonnet kept every value, but left a BEGIN in a file meant for D1, which D1 refuses, and quietly turned a POINT column into text instead of saying it cannot be carried over: 22 right, 24 with the file. Haiku went from 21 to 23. You get plain SQL, ready for sqlite3 or wrangler d1 execute.

## Related skills

- [D1 Migration Writer: SQLite Migrations That Apply](https://aiskills402.com/skills/d1-migration-writer.md): $0.07 once
- [SQL Query Optimizer for D1, SQLite and Turso](https://aiskills402.com/skills/sql-query-optimizer.md): $0.05 once
- [CSV Repair: Fix the Form, Keep Every Cell](https://aiskills402.com/skills/csv-repair.md): $0.05 once

## Measurement limits

- Models other than the two named above were not run.
- Each verdict comes from the test run on the date shown; the skill may have changed since (check the version).
- Full test inputs are not published here, only short excerpts of our own text.
- Results on your own texts, languages and domains can differ.

Offer note: Paid in USDC (USD-pegged) over x402 by an AI agent; one-time.
