Paste a mysqldump, a phpMyAdmin export or just CREATE TABLE statements and get PostgreSQL-ready SQL. Backticks, AUTO_INCREMENT, MySQL-only types, ENUMs, engine and charset clauses, zero dates and string escapes are converted, and anything that needs a human decision is listed in the review notes.
Last updated:
Review notes
Conversion options
Advertisement
Advertisement
How to use the MySQL to PostgreSQL Converter
Paste your MySQL SQL or open a .sql file. A sample dump is loaded so you can see the result first.
Pick the options that match your target design: identity or serial, how to store ENUMs, timestamps with or without time zone.
Read the review notes under the buttons; they list functions, routines and values that need a decision.
Download the .sql file or copy it, then run it with psql, for example psql -d mydb -f sample-postgres.sql.
Test on a copy first and compare row counts between the two databases.
MySQL to PostgreSQL type mapping
MySQL
PostgreSQL
Notes
TINYINT(1), BIT(1), BOOL
BOOLEAN
0/1 values become false/true. Other TINYINT widths become SMALLINT.
TINYINT, SMALLINT
SMALLINT
SMALLINT UNSIGNED becomes INTEGER so values up to 65,535 still fit.
MEDIUMINT, INT
INTEGER
INT UNSIGNED becomes BIGINT (PostgreSQL has no unsigned types).
BIGINT
BIGINT
BIGINT UNSIGNED above 263−1 needs NUMERIC(20).
INT AUTO_INCREMENT
INTEGER GENERATED BY DEFAULT AS IDENTITY
Or SERIAL / BIGSERIAL.
FLOAT / DOUBLE
REAL / DOUBLE PRECISION
Use NUMERIC for money and exact values.
DECIMAL(p,s)
NUMERIC(p,s)
A bare DECIMAL means DECIMAL(10,0) in MySQL.
VARCHAR(n), CHAR(n)
same
Character set and collation clauses are removed.
TINYTEXT … LONGTEXT
TEXT
PostgreSQL TEXT has no small/medium/long variants.
BLOB, VARBINARY, BINARY
BYTEA
Hex literals (0x… or X'…') become '\x…'.
DATETIME(n)
TIMESTAMP(n)
Or TIMESTAMPTZ if you store moments in time across zones.
TIMESTAMP
TIMESTAMP / TIMESTAMPTZ
MySQL TIMESTAMP is stored in UTC, which matches TIMESTAMPTZ.
YEAR
SMALLINT
Add a CHECK if you need the 1901-2155 range.
JSON
JSONB
JSONB is indexed and compared faster; JSON keeps key order and whitespace.
ENUM('a','b')
CREATE TYPE … AS ENUM
Or VARCHAR + CHECK, or TEXT.
SET('a','b')
VARCHAR
Consider TEXT[] or a join table.
GEOMETRY, POINT…
PostGIS geometry
Requires the PostGIS extension.
Syntax that changes
MySQL
PostgreSQL
`order`
"order" (reserved words stay quoted)
'O\'Neil', 'a\nb'
'O''Neil', E'a\nb'
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
removed (the database encoding applies)
KEY idx (col) inside CREATE TABLE
CREATE INDEX idx ON table (col);
INSERT IGNORE
INSERT … ON CONFLICT DO NOTHING
ON DUPLICATE KEY UPDATE a = VALUES(a)
ON CONFLICT (id) DO UPDATE SET a = EXCLUDED.a
IFNULL(a, b), IF(c, x, y)
COALESCE(a, b), CASE WHEN c THEN x ELSE y END
GROUP_CONCAT(x SEPARATOR ';')
STRING_AGG((x)::text, ';')
LIMIT 10, 20
LIMIT 20 OFFSET 10
CURDATE(), UNIX_TIMESTAMP()
CURRENT_DATE, EXTRACT(EPOCH FROM CURRENT_TIMESTAMP)::bigint
col REGEXP 'x'
col ~* 'x' (MySQL regex matching is case-insensitive by default)
A safe migration checklist
Dump the schema and data: mysqldump --single-transaction --skip-triggers --hex-blob dbname > dump.sql. --hex-blob keeps binary data exact.
Convert the dump here and read every review note.
Create an empty database with UTF-8 encoding and run the script with psql -v ON_ERROR_STOP=1 -d newdb -f dump-postgres.sql so it stops at the first error.
Compare row counts per table, then spot-check dates, booleans, decimals and text with accents or emoji.
Update application queries: MySQL-specific functions, LIMIT x, y, case-insensitive string comparison (PostgreSQL's = is case-sensitive; use ILIKE or citext), and backticks in code.
For translating individual queries between many SQL dialects, use the SQL Dialect Converter. To tidy the result, run it through the SQL Formatter.
Frequently asked questions
How do I convert a MySQL dump to PostgreSQL?
Export with mysqldump (or phpMyAdmin's SQL export), open the file here and download the converted script. Create an empty database in PostgreSQL and run the script with psql -d dbname -f file.sql. The converter removes MySQL-only statements, rewrites types and syntax, adds foreign keys after the data and resets sequences at the end.
What does AUTO_INCREMENT become in PostgreSQL?
By default an identity column: id INTEGER GENERATED BY DEFAULT AS IDENTITY, the SQL-standard approach recommended since PostgreSQL 10. You can choose SERIAL or BIGSERIAL instead. Both are backed by a sequence, and the script moves the sequence past the highest inserted id so new rows do not collide.
Why are backticks replaced?
MySQL quotes identifiers with backticks, while PostgreSQL uses double quotes and folds unquoted names to lowercase. By default names are lowercased and left unquoted unless they are reserved words or contain unusual characters, so you can write queries without quotes. Choose Keep case if your application relies on mixed-case names.
How are MySQL ENUM columns converted?
PostgreSQL has real enum types, so each ENUM column becomes a CREATE TYPE table_column AS ENUM (…) followed by a column of that type. Alternatively you can store the value in a VARCHAR with a CHECK constraint listing the allowed values, which is easier to change later, or as plain TEXT.
What happens to TINYINT(1) and zero dates?
TINYINT(1) and BIT(1) are MySQL's usual way to store booleans, so they become BOOLEAN and inserted 0/1 values become false/true. PostgreSQL rejects dates such as '0000-00-00', so zero dates in INSERTs become NULL and zero-date defaults are removed; NOT NULL columns that held zero dates need a real default.
Does it convert stored procedures and triggers?
No. MySQL routines and triggers use a different procedural language, so blocks between DELIMITER lines and CREATE PROCEDURE/FUNCTION/TRIGGER statements are kept as comments for you to rewrite in PL/pgSQL. The only trigger generated automatically is the one that replaces ON UPDATE CURRENT_TIMESTAMP.
Is my database dump uploaded?
No. The conversion is plain JavaScript running in your browser tab, so table definitions and data never leave your computer. Very large dumps (hundreds of megabytes) are better handled with a dedicated migration tool such as pgloader.
Are all the tools on FreeToolCabin tested for quality and accuracy?
Yes! Every tool on our site undergoes automated Q/A testing in real browser environments to ensure high precision, correct output, and zero errors. If you happen to spot a bug or have a suggestion, please contact us at [email protected] and our team will review it right away.