Bom, precisei esta semana migrar um banco de dados de postgres para MySQL …
A primeira tentativa foi utilizar o proprio MySQL Migration Tool, mas não deu certo por que ele não tem suporte nativo ao Postgres e se perdia direto nos campos Data, fazendo com que em qualquer tabela que tivesse um tampo Timestamp, ele não inserisse nenhuma linha …
Mas percebi que o Migration tool estava criando o schema corretamente no MySQL.
o que precisei fazer foi comentar a parte do schema que criava os relacionamentos e constraints, pois isto iria dificultar muito a migração dos dados.
e depois escrevi um pequeno programa java, que na verdade só tem uma classe pois foi escrito em 5 minutos, utilizando um pouquinho de JDBC nativo, não esta perfeitamente organizado, demora horas para rodar em um banco de dados com milhões de registros, mas funciona
E como isto foi para mim mesmo que precisei fazer, nenhum cliente estava me pagando para desenvolver isto, segue um passo a passo de migração MySQL -> PostgresSQL.
- Adicionar o jar do PostgreSQL no diretório lib do MySQL Migration Tool
- Rodar o Migration Tool informando corretamente as informações de conexão aos bancos de dados.
- na criação do Schema, marcar o checkbox que diz que deve ser criado um .sql
- Abrir o .sql e comentar as constraints
- executar o sql
- Executar o programa Migration.java
- alterar o sql para executar alter table(s) e adicionar as contraints
- Tudo pronto
Segue o código do programa, não esta perfeito, mas acho que pode pelo menos servir de exemplo para alguem.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | package teste; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; public class Migrate { public static void main(String[] args) { try { Class.forName("com.mysql.jdbc.Driver"); Class.forName("org.postgresql.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } try { Connection source = DriverManager.getConnection("jdbc:postgresql:db", "postgres", "postgres"); try { Connection destination = DriverManager.getConnection("jdbc:mysql:///db", "root", "admin"); try { DatabaseMetaData meta = source.getMetaData(); ResultSet tables = meta.getTables(null, null, null, new String[] { "TABLE" }); HashMap<string, ArrayList<string>> tableNames = new HashMap<string, ArrayList<string>>(); try { while (tables.next()) { tableNames.put(tables.getString(3), new ArrayList<string>()); } } finally { tables.close(); } for (String table : tableNames.keySet()) { ArrayList<string> columns = tableNames.get(table); ResultSet colNames = meta.getColumns(null, null, table, null); try { while (colNames.next()) { columns.add(colNames.getString(4)); } } finally { colNames.close(); } } for (Map.Entry<string, ArrayList<string>> table : tableNames.entrySet()) { prepareCopy(source, destination, table); } } finally { destination.close(); } } finally { source.close(); } } catch (SQLException e) { e.printStackTrace(); } } private static void prepareCopy(Connection source, Connection destination, Map.Entry<string, ArrayList<string>> table) throws SQLException { String selectSql = buildSelectSQL(table.getKey(), table.getValue()); String deleteSql = buildDeleteSQL(table.getKey(), table.getValue()); String insertSql = buildInsertSQL(table.getKey(), table.getValue()); System.out.println(selectSql); System.out.println(deleteSql); System.out.println(insertSql); doDelete(destination, deleteSql); Statement st = source.createStatement(); try { ResultSet sres = st.executeQuery(selectSql); try { PreparedStatement pst = destination.prepareStatement(insertSql); try { int size = table.getValue().size(); while (sres.next()) { doCopyLine(sres, pst, size); } } finally { pst.close(); } } finally { sres.close(); } } finally { st.close(); } } private static void doCopyLine(ResultSet sres, PreparedStatement pst, int size) throws SQLException { for (int i = 0; i < size; i++) { pst.setObject(i + 1, sres.getObject(i + 1)); } pst.execute(); } private static void doDelete(Connection destination, String deleteSql) throws SQLException { Statement dst = destination.createStatement(); try { dst.execute(deleteSql); } finally { dst.close(); } } private static String buildDeleteSQL(String key, ArrayList<string> value) { return "delete from " + key; } private static String buildInsertSQL(String key, ArrayList<string> value) { StringBuilder sb = new StringBuilder(); sb.append("insert into ").append(key).append(" ("); for (String col : value) { sb.append(col).append(","); } int idx = sb.lastIndexOf(","); sb.replace(idx, idx + 1, ") values ("); for (int i = 0; i < value.size(); i++) { sb.append("?,"); } idx = sb.lastIndexOf(","); sb.replace(idx, idx + 1, ")"); return sb.toString(); } private static String buildSelectSQL(String key, ArrayList<string> value) { StringBuilder sb = new StringBuilder(); sb.append("select "); for (String col : value) { sb.append(col).append(","); } int idx = sb.lastIndexOf(","); sb.replace(idx, idx + 1, " from "); sb.append(key); return sb.toString(); } } |

Urubatan, que tal usar batch para melhorar (e muito) a performance do teu Migration.java?
valeuz…
iria ajudar bastante mesmo

mas só lembrei que isto existia depois que terminei de testar
mas gostei da ideia, vou alterar o exemplo para usar batch e atualizar o post
Urubatan não estou conseguindo visualizar o código clompletamento o meu navegador comeu parte dó código, vc pode mandá-lo para meu email?
por favor!!
obrigado!!!
ok..
eu copiei para word deu crrto ok… valeu
Opa, só vi o comentário agora, sorry
Preciso de usar este código, mas tem muitas falhas de “incompatible types” o 1º ocorre aqui:
….
for (ArrayList table : tableNames.keySet()) {
….
obrigado por avisar, era problema de formatação no HTML, ele achou que algumas partes do código eram tags.
ja esta corrigido.