# TuskShift > Free, tested tools for moving Laravel apps from MySQL to PostgreSQL: a schema risk check, a Postgres error-to-fix lookup, a MySQL-to-Postgres SQL translator, a MySQL-to-Postgres schema (DDL) converter, and tuskshift-pg-migrate, a zero-dependency MCP server + CLI + skill that gives AI coding agents the same rules. The browser tools run locally and upload nothing. Rules were tested on MariaDB 11.8 and PostgreSQL 17. Install the MCP server (Node 18+, no dependencies, no telemetry; the only network call is a Gumroad license check for Pro): ``` claude mcp add tuskshift-pg-migrate -- npx -y --package=https://tuskshift.deed.page/tuskshift-pg-migrate-1.0.1.tgz tuskshift-pg-migrate ``` Tools in the MCP server: check_mysql_schema (free), lookup_postgres_error (free), translate_mysql_query (free, up to 5 statements per call), convert_mysql_schema (Pro; free shows 2 tables), scan_laravel_project (Pro; free shows totals and 3 findings), activate_license. Pro is $39 one-time. ## Tools - [Schema risk check](https://tuskshift.deed.page/): paste SHOW CREATE TABLE, mysqldump --no-data or Laravel migrations; get what breaks on Postgres, most dangerous first - [Postgres error to fix](https://tuskshift.deed.page/errors): paste a Postgres error a Laravel app hits after leaving MySQL; get the cause and a tested fix (12 entries) - [MySQL to Postgres SQL translator](https://tuskshift.deed.page/translate): paste MySQL queries or DB::raw / whereRaw fragments; get Postgres SQL with a reason for each change - [MySQL to Postgres schema converter](https://tuskshift.deed.page/ddl): paste SHOW CREATE TABLE, mysqldump --no-data or a phpMyAdmin export; get Postgres DDL in run order (tables, indexes, triggers, foreign keys, sequence resets) - [Tools for AI coding agents](https://tuskshift.deed.page/agents): install lines for Claude Code, Cursor, Windsurf, Codex and Claude Desktop, tool list, test results, SHA256 checksums ## MCP server and skill downloads - [tuskshift-pg-migrate-1.0.1.tgz](https://tuskshift.deed.page/tuskshift-pg-migrate-1.0.1.tgz): npm package tarball (MCP server + CLI), run with `npx -y --package=https://tuskshift.deed.page/tuskshift-pg-migrate-1.0.1.tgz tuskshift-pg-migrate` - [tuskshift-pg-migrate-1.0.1.mcpb](https://tuskshift.deed.page/tuskshift-pg-migrate-1.0.1.mcpb): one-click bundle for Claude Desktop - [tuskshift-pg-migrate-skill.zip](https://tuskshift.deed.page/tuskshift-pg-migrate-skill.zip): skill file for Claude Code (audit, scan, convert, test, fix workflow); unzip into ~/.claude/skills/ ## MySQL to Postgres gotchas - [23505 duplicate key value violates unique constraint "users_pkey"](https://tuskshift.deed.page/laravel-postgres-duplicate-key-violates-unique-constraint): ids copied from MySQL but the Postgres sequence still starts at 1; fix with setval(pg_get_serial_sequence(...), MAX(id)+1, false) - [42803 column "users.name" must appear in the GROUP BY clause or be used in an aggregate function](https://tuskshift.deed.page/laravel-postgres-must-appear-in-group-by-clause): Postgres rejects selecting non-grouped columns that MySQL allowed; aggregate them, group by the primary key, or use DISTINCT ON - [22003 value "3000000000" is out of range for type integer](https://tuskshift.deed.page/laravel-postgres-out-of-range-for-type-integer): no unsigned integers in Postgres; unsignedInteger()/increments() become integer (max 2,147,483,647); use bigint - [42883 operator does not exist: boolean = integer](https://tuskshift.deed.page/laravel-postgres-operator-does-not-exist-boolean-integer): tinyint(1) became boolean; a literal 1 in raw SQL fails, use true or bind the value - [42883 operator does not exist: character varying = integer](https://tuskshift.deed.page/laravel-postgres-operator-does-not-exist-character-varying-integer): string column compared with a bare number in raw SQL; quote or bind it - [22008 date/time field value out of range: "0000-00-00 00:00:00"](https://tuskshift.deed.page/laravel-postgres-0000-00-00-date-out-of-range): MySQL zero dates ('0000-00-00') don't exist in Postgres; set them to NULL on MySQL before copying (column must allow NULL) - [42703 column "a@x.com" does not exist](https://tuskshift.deed.page/laravel-postgres-column-does-not-exist-double-quotes): double quotes mean identifiers in Postgres, not strings; use single quotes - [42601 syntax error at or near "`"](https://tuskshift.deed.page/laravel-postgres-syntax-error-at-or-near-backtick): backtick identifiers are MySQL-only; remove them or use double quotes - [42883 function ifnull(text, unknown) does not exist](https://tuskshift.deed.page/laravel-postgres-function-ifnull-does-not-exist): MySQL-only functions (IFNULL, GROUP_CONCAT, DATE_FORMAT...) need Postgres equivalents (COALESCE, string_agg, to_char) - [22021 invalid byte sequence for encoding "UTF8": 0x00](https://tuskshift.deed.page/laravel-postgres-invalid-byte-sequence-utf8-0x00): Postgres text can't store the NUL byte (0x00); strip it before loading - [25P02 current transaction is aborted, commands ignored until end of transaction block](https://tuskshift.deed.page/laravel-postgres-current-transaction-is-aborted): after any error inside a transaction Postgres ignores every later statement until rollback; fix the first error, or wrap the risky step in a savepoint - [(no error) search or login finds nothing: WHERE email LIKE ... returns 0 rows](https://tuskshift.deed.page/laravel-postgres-like-case-sensitive-no-rows): no error, but MySQL _ci collations were case-insensitive and Postgres = and LIKE are not; use ILIKE, lower() or citext ## Optional - [Full text of all rules](https://tuskshift.deed.page/llms-full.txt): every error entry with its fix, the schema checks, the SQL translation rules and the schema converter notes, as plain text - [tuskshift-pg-migrate Pro](https://tuskshift.gumroad.com/l/pg-migrate-pro?utm_source=deed-llms): $39 one-time; full schema conversion, full project scan, batch translation - [Laravel MySQL to Postgres Migration Kit](https://tuskshift.gumroad.com/l/tuskshift?utm_source=deed-llms): $49; schema, data checks, rehearsal, cutover and rollback - [Laravel Postgres Error Fix Pack](https://tuskshift.gumroad.com/l/laravel-postgres-error-fix-pack?utm_source=deed-llms): $19; tested fix scripts for the common post-migration errors - [Read-only MySQL data checker](https://tuskshift.gumroad.com/l/zkabsa?utm_source=deed-llms): free PHP file (MIT) that finds data problems before the move