El Weblog de Juan Carlos

« The pragmatic progra... | Main

20040710 sábado julio 10, 2004

Traspaso de datos de Access a MySQL

Pues ese es el problema...

Estoy metido en un trabajillo de migrar una antigua aplicación que corria sobre Microsoft Access a una nueva version, que use MySQL. Lo que pasa es que como siempre, se deben conservar los antiguos datos. La estructura de tablas en Access es muy sencilla, sin relaciones de ningun tipo, o sea que la migracion no seria muy complicada si no fuera porque existen ... más de 5.000 registros!

He estado probando de pasar a un fichero de texto plano toda la información de las tablas de Access y recuperarla desde MySQL, pero la cosa no acaba de funcionar tan bien como deberia.

Por lo tanto, tengo pendiente de evaluar algunas aplicaciones que prometen realizar este paso sin ninguna complicación, y son las siguientes:

Si alguien conociera alguna de estas soluciones u otra y la pudiera recomendar pues le estaria muy agradecido, y si encima fuera de codigo abierto y gratuita... pues cojonudo!

Si no, aportare mis conclusiones personales de lo que me han parecido mis pequeñas pruebas, a ver si alguna de estas herramientas resuelve mis problemas. (2004-07-10 21:22:56.0) Permalink Comentarios [11]

URL de la referencia: http://weblogs.javahispano.org/jcarlos/entry/traspaso_de_datos_de_access
Comentarios:

¿Le has echado un vistazo a <a href="http://dbmt.sourceforge.net/">DBMT</a>?

Además, es de la <a href="http://www.javahispano.org">casa</a>.

Enviado por Tx en julio 12, 2004 a las 07:54 AM GMT+01:00 #

&lt;publicidad&gt;<br/>
Sobre <a href="http://dbmt.sf.net">DBMT</a>. Basicamente la aplicación permite realizar migraciones <i>prediseñadas</i> basandose en un -joder que mania- XML. EN el momento actual y aunque desgraciadamente no esta disponible en una version nueva el proyecto esta bastante avanzado respecto a a la version 1.1 y se pretende que en la proxima version se introduzca el diseñador grafico que se ha realizado basado en XMLFaces.<br/>
<br/>
Respecto a la migracion particular que citas hace muy poco he tenido que realizar una similares carateristicas aunque el volumen de los datos origen era algo mas grande. La migracion (realizada en un Pentium 4 1.6 Ghz 256Mb RAM) de una tabla de 40.656 registros (la mas grande) llevo 196,063 segundos, es decir algo mas de 3 minutos, aunque hay que tener en cuenta que a parte de la lectura del origen (select) y la actualizacion en el destino (insert), yo utilizaba dos funciones (ejecuciones de sql en cada paso) para conseguir datos relacionados de una tercera y una cuarta tabla (otras dos select mas) elevando el numero de SQLs que manejo el aplicativo hasta 162.624. <br/>
<br/>
Te animaria a que probases el aplicativo en la version que hay en SF. Es posible que te pueda dar algun error por el caracter estricto que tiene el puente JDBC-ODBC para acceder a Access (por ejemplo no se pueden leer dos veces la misma columna en la misma pasada de un ResultSet). Si fuera asi contacta conmigo para que te pueda pasar la version de desarrollo en que estos problemas estan corregidos hasta que se libere la version nueva en SF.<br/>
<br/>
Un saludo,<br/>
Aitor Garcia<br/>
DBMT Developer.<br/>
<br/>
&lt;/publicidad&gt;

Enviado por Aitor García Rey en julio 12, 2004 a las 09:09 AM GMT+01:00 #

Pues tendremos que darle un ojo...<p>
Gracias!

Enviado por jcarlos en julio 13, 2004 a las 11:20 AM GMT+01:00 #

Buah!, Aitor, casi pareces hasta bueno vendiendo ;-).

Pero en serio, Juan Carlos, a ver si un día aitor acaba de hacer los commits de esasp artes y podemos seguir avanzando con la herramienta.

Enviado por Al en julio 13, 2004 a las 12:55 PM GMT+01:00 #

No hace mucho le envié a Alberto unos <i>arreglilios</i> sobre el DBMT 1.1, básicamente en el tratamiento de fechas, añadí el tipo double y el tratamiento de NULL, es decir ahora si se recibe un NULL, se detecta y se escribe en el destino (se asume que es también nulable).<br />
Ah, también le añadí la opción de que además de poder leer de una tabla, se pudiera leer de una "select" (permitiendo mega-Joins complejas).
<br />
Yo la he usado para hacer un traspaso que no era simétrico (tabla a tabla) y me ha ido muy bien, más que nada, por poder controlar vía el fichero XML, todo el proceso.
<br /><br />
Aunque le he hechado en falta alguna pequeña cosilla cumple muy bien su cometido y además está muy bien diseñada (patrones powered), por lo que es fácil ampliarla.

Enviado por Feli en octubre 08, 2004 a las 09:41 AM GMT+01:00 #

También tienes <b>db2db</b> que además permite mapear los tipos específicos del rdbms con tipos jdbc y traspasar, además de los datos, las estructuras de las tablas, índices, primary keys y foreign keys
<a href="http://db2db.sourceforge.net/screenshots.html">
http://db2db.sourceforge.net</a>.

Enviado por Feli en octubre 08, 2004 a las 02:04 PM GMT+01:00 #

MySql funciona muchsimo mejor que Access...sin duda..el rendimiento es mayor ;)

Enviado por Bittorrent en diciembre 31, 2004 a las 12:06 AM GMT+01:00 #

Hola Juan Carlos,

supongo que ya tendrás el problema resuelto desde hace mucho tiempo, pero por si acaso....

hace tiempo tuve el mismo problema, y conseguí exportar la extructura con un programa llamado access2mysql o algo asi, y para exportar los datos (la con la estructura ya creada) me hice un programilla con java que lo hacía.
Lo hice a la carrera en una media hora, y el código esta un poco chapucero, pero solo era para una vez y además era solo por una curiosidad personal (a ver si va más rapido access con las tablas de MySql vinculadas que access solo en aplicaciones con varios usuarios conectados).

Te posteo el código:

package com;
import java.sql.*;
import java.util.*;
import java.lang.reflect.*;

public class principal
{

private Connection conexionAccess=null;
private Connection conexionMySQL=null;

public principal() throws Exception{
abrirConexiones();
List listaTablas = obtenerListadoTablas();
Map tabla=null;
for (int i = 0; i < listaTablas.size(); i++) {
tabla=obtenerCamposTabla((String)listaTablas.get(i));
exportaDatos((String)listaTablas.get(i),tabla);
}
}

public List obtenerListadoTablas()throws SQLException{
List listaTablas= new ArrayList();
PreparedStatement stmt = null;
ResultSet rs = null;
String sentencia = "show tables";
stmt=conexionMySQL.prepareStatement(sentencia);
rs=stmt.executeQuery();
while(rs.next()){
listaTablas.add(rs.getString(1));
}
return listaTablas;
}

public Map obtenerCamposTabla(String tabla)throws SQLException{
Map camposTabla= new HashMap();
PreparedStatement stmt = null;
ResultSet rs = null;
String sentencia = "describe " + tabla;
stmt=conexionMySQL.prepareStatement(sentencia);
rs=stmt.executeQuery();
while(rs.next()){
camposTabla.put(rs.getString(1),rs.getString(2));
}
return camposTabla;
}

public void exportaDatos(String tabla, Map campos) throws Exception{
StringBuffer sentenciaInsert= new StringBuffer();
String sentenciaSelect="select * from "+tabla;
sentenciaInsert.append("insert into " + tabla + " (");
Iterator iteradorCampos=campos.keySet().iterator();
while(iteradorCampos.hasNext()){
sentenciaInsert.append(iteradorCampos.next());
if(iteradorCampos.hasNext()){
sentenciaInsert.append(", ");

}
}
sentenciaInsert.append(") values ( ");
iteradorCampos=campos.keySet().iterator();
while(iteradorCampos.hasNext()){
sentenciaInsert.append("?");
iteradorCampos.next();
if(iteradorCampos.hasNext()){
sentenciaInsert.append(", ");
}
}
sentenciaInsert.append(")");
iteradorCampos=campos.keySet().iterator();
List listaMetodosGet = new ArrayList();
List listaMetodosSet = new ArrayList();
List valoresParametros= new ArrayList();
Class claseRS = Class.forName("java.sql.ResultSet");
Class claseSTMT = Class.forName("java.sql.PreparedStatement");

String tipoCampo=null;
while(iteradorCampos.hasNext()){
Class [] parametrosRS= new Class[1];
Class [] parametrosSTMT= new Class[2];
Method metodo=null;
String nombreCampo=(String)iteradorCampos.next();
tipoCampo=(String)campos.get(nombreCampo);
valoresParametros.add(nombreCampo);
parametrosRS[0]=Class.forName("java.lang.String");
parametrosSTMT[0]=int.class;
parametrosSTMT[1]=Class.forName("java.lang.String");
if(tipoCampo.toLowerCase().indexOf("char")>=0 || tipoCampo.toLowerCase().indexOf("text")>=0){
metodo=claseRS.getMethod("getString",parametrosRS);
listaMetodosGet.add(metodo);
metodo=claseSTMT.getMethod("setString",parametrosSTMT);
listaMetodosSet.add(metodo);
}else if(tipoCampo.toLowerCase().indexOf("date")>=0){
metodo=claseRS.getMethod("getDate",parametrosRS);
listaMetodosGet.add(metodo);
parametrosSTMT[1]=Class.forName("java.sql.Date");
metodo=claseSTMT.getMethod("setDate",parametrosSTMT);
listaMetodosSet.add(metodo);
}else{
metodo=claseRS.getMethod("getLong",parametrosRS);
listaMetodosGet.add(metodo);
parametrosSTMT[1]=long.class;
metodo=claseSTMT.getMethod("setLong",parametrosSTMT);
listaMetodosSet.add(metodo);

}
}
System.out.println(sentenciaInsert);
PreparedStatement stmtSelect = conexionAccess.prepareStatement(sentenciaSelect);
ResultSet rsSelect = stmtSelect.executeQuery();
PreparedStatement stmtInsert=conexionMySQL.prepareStatement(sentenciaInsert.toString());
Object [] parametrosS= new Object[2];
Object [] parametrosG= new Object[1];
while(rsSelect.next()){
for (int i = 0; i < listaMetodosGet.size(); i++){
Method metodoGet = (Method)listaMetodosGet.get(i);
Method metodoSet= (Method)listaMetodosSet.get(i);
parametrosG[0]=valoresParametros.get(i);
parametrosS[0]=new Integer(i+1);
parametrosS[1]=metodoGet.invoke(rsSelect,parametrosG);

metodoSet.invoke(stmtInsert,parametrosS);
}
stmtInsert.executeUpdate();

}
}

public void abrirConexiones(){
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
conexionAccess=DriverManager.getConnection("jdbc:odbc:secreAccess");
conexionMySQL=DriverManager.getConnection("jdbc:odbc:secreMySQL");
}catch (Exception e){
e.printStackTrace();
}
}

public static void main(String[] args) throws Exception
{
principal principal = new principal();
}
}

Como verás las conexiones estan picadas a pelo (ya digo que esta todo muy chapucero). Tendrás que modificarlo para que te valga a ti y compilarlo y ejecutarlo.

Venga un saludo

Javier Murciego

Enviado por Javier Murciego en enero 15, 2005 a las 06:51 PM GMT+01:00 #

Mira, baje el access2mysql, traspase la estructura,luego instale mysqlodbc 3.51 , arme una base access, vincule las tablas de mysql y luego exporte los datos entre dos base access.
El problema que tuve fue con los campos memos, en access 32k y el tinytext es 64K ,tuve algunos problemas en los objetos que mostraban dicho campo.Espero te sirva

Enviado por teodoro en agosto 31, 2005 a las 05:10 PM GMT+01:00 #

bajate el odbc de mysql.com
lo intalas
creas un enlaze a la base mysql en herramientas odbc
y luego exportas las tablas directamente a mysql desde access sin ningun utilitario y las veces que quieras, seleccionando el odbc que creastes

Saludos

Nelson Stuardo

Enviado por Nelson Stuardo en agosto 16, 2006 a las 07:38 PM GMT+01:00 #

Yo use Migration Tool Kit, es excelecte para lo que tu necesitas. Lo baje www.mysql.com

Enviado por ehsaenz en marzo 27, 2007 a las 07:21 AM GMT+01:00 #

Enviar un comentario:

Nombre:
Correo electrónico:
URL:

Su comentario:

Sintaxis HTML: Deshabilitado