Migrando banco de MySQL → PostgreSQL
Esse tutorial segue exatamente o fluxo que funcionou pra mim, não usei pgloader pois simplesmente não funcionou pra mim.
Aqui a ideia é simples:
- Tirar os dados do MySQL
- Converter o dump
- Subir só os INSERTs no Postgres
- Manter o schema (Prisma ou não) intacto (bem, isso eh meu caso pois eu usava prisma nessa migração em específico)
Visão geral do fluxo
- Dump do MySQL usando
mysqldump(via Docker) - Script pra:
- Remover
CREATE TABLE - Ignorar
_prisma_migrations - Ajustar aspas, JSON, nomes de colunas
- Remover
- Importar no Postgres usando
psql(via Docker)
Recomendação minha, sem instalações locais, taca no Docker para facilitar sua vida no futuro
Dump do MySQL (Docker)
docker run --rm \
mysql:8 \
mysqldump \
-h host.docker.internal \
-u root \
-p banco_antigo > dump.sql
Esse dump vai vir com tudo: schema, migrações, etc.
A limpeza acontece no próximo passo.
Quando o banco vem do Prisma (importante)
Se o schema do Postgres foi criado pelo Prisma:
- ❌ NÃO importa
CREATE TABLE - ❌ NÃO importa
_prisma_migrations - ✅ Importa somente os INSERTs
Pela minha experiência, sempre deu problema ao mandar os CREATE TABLE e o _prisma_migrations
Script de conversão, onde vai fazer funcionar mesmo
Esse script foi o que usei pra converter o dump do MySQL em algo que o Postgres aceita.
Outra coisa, precisa do certificado SSL tá? caso o banco esteja hospedado em algum lugar na maioria das vezes, eu precisei usar o certificado para autorizar as transações
Vou subir isso num Gist, mas o script é esse 👇
#!/bin/bash
# Author: Francisco Juan
# Converte dump MySQL para PostgreSQL e importa
# Remove migrações do Prisma e CREATE TABLE, mantém apenas INSERTs
DUMP_FILE="${1:-dump.sql}"
OUTPUT_FILE="dump_postgres_fixed.sql"
DB_URL="${DATABASE_URL:-postgresql://user:pass@host:port?sslmode=require}"
if [ ! -f "$DUMP_FILE" ]; then
echo "Erro: Arquivo $DUMP_FILE não encontrado!"
echo "Uso: $0 [arquivo_dump.sql]"
exit 1
fi
echo "Processando dump MySQL..."
# Extrai apenas INSERTs, ignora _prisma_migrations e remove coisas do MySQL
grep -E "^INSERT INTO" "$DUMP_FILE" | \
grep -v "_prisma_migrations" | \
sed -E \
-e 's/`([^`]+)`/\1/g' \
-e 's/\\\\"/"/g' \
-e "s/\\\\'/''/g" > "$OUTPUT_FILE"
if [ ! -s "$OUTPUT_FILE" ]; then
echo "Erro: Nenhum INSERT encontrado no arquivo!"
exit 1
fi
echo " - Arquivo processado: $OUTPUT_FILE ($(wc -l < "$OUTPUT_FILE") linhas)"
echo "Importando no PostgreSQL..."
docker run --rm -i \
-v "$(pwd)/$OUTPUT_FILE:/tmp/dump.sql:ro" \
-v "$(pwd)/../ca-certificate-postgreen.crt:/tmp/ca-cert.crt:ro" \
postgres:18 \
psql "$DB_URL" \
-f /tmp/dump.sql
if [ $? -eq 0 ]; then
echo "✅ Importação concluída com sucesso!"
else
echo "❌ Erro na importação!"
exit 1
fi
Subindo os dados no Postgres
O próprio script já faz isso via Docker:
docker run --rm -i postgres:18 \
psql "$DATABASE_URL" \
-f dump_postgres_fixed.sql
Problemas comuns (e onde olhar)
Se der erro, quase sempre é:
- JSON mal escapado
- aspas simples / duplas
- coluna que não existe no schema atual
- ordem de inserts (FK)
Dica:
- começa por tabelas sem FK
- depois as dependentes
Resumo rápido
- pgloader não funcionou comigo
- Dump + script resolveu
- Prisma exige só INSERT
- Docker em tudo
- Zero instalação local