viernes, 15 de junio de 2007

Howto: Exportar de mdb a sqlite en GNU/Linux.

Objetivo: pasar las tablas de una base de datos de Microsoft Access (.mdb) a un archivo sqlite.

Razón: Muchas veces necesitamos hacer búsquedas y no nos sirve usar bases de datos en mysql, un ejemplo puede ser un programa. Puedo querer guardar alguna información, pero puede que la persona que vaya a usar ese programa no tenga mysql instalado o no sepa configurarlo, instalarlo, etc. sqlite nos soluciona el problema, pues es un fichero que puede ser adjuntado con el programa, y nos aporta las ventajas de las bases de datos, aunque en un nivel menos, pues no soporta todas las opciones que nos puede dar mysql. Podríamos guardar los datos en un archivo de texto o binario, pero a la hora de recuperar los datos, sqlite es mucho mejor que un archivo.

Como empezar: Vamos a poner de ejemplo, que queremos pasar la base de datos de todas las cartas de magic, y ya tenemos el mdb. Para trabajar con las bases de datos tenemos el paquete mdbtools, y para trabajar con sqlite el paquete sqlite3, así que pasamos a instalarlos:
sudo apt-get install sqlite3 mdbtools

Una vez que tenemos los paquetes, pasamos a exportar del archivo mdb a sentencias sql, lo haremos en dos pasos, primero el esquema (CREATE …) y luego los datos (INSERT INTO ….) . Para exportar el esquema usaremos el siguiente comando:
mdb-schema master.mdb > esquema.sql

El primer parámetro sera el nombre de la base de datos y el segundo el archivo con las sentencias sql. Si vemos el archivo vemos que uno de los campos se llama P/T y que hay dos campos de tipo Memo/Hyperlink (255), pues bien, sqlite no permite poner “/” en los nombres de los campos, y no existen campos de ese tipo, así que con kate, editaremos el archivo y pondremos de nombre del campo PT y el tipo de datos Text(255).

Ahora pasaremos a por el archivo de los datos, para ello, usaremos el comando:
mdb-export -H -I master.mdb Cards > datos.txt

Con esto exportamos los datos con las sentencias INSERT ya incluidas. Cards es el nombre de la tabla, podemos verlo con mdb-tables master.mdb. Pero tenemos dos problemas que hay que solucionar, el primero es que en los INSERT nos ha puesto el campo P/T, y lo hemos cambiado por PT, y el segundo problema es que las sentencias insert no terminan en “;”. Para arreglar eso echaremos mano de sed.
cat datos.txt | sed -e 's/")/");/g' > datos.temp

Con esto añadimos el ; al final de cada sentencia insert, y para cambiar P/T por PT, basta con:
cat datos.temp | sed -e 's/P\/T/PT/g' > datos.sql

Estupendo, ya tenemos todo lo necesario para crear las tablas en sqlite, el proceso es muy sencillo. ejecutamos estas sentencias:
josu@cyrusnet:$ sqlite
SQLite version 2.8.17
Enter “.help” for instructions
sqlite> .read esquema.sql
DROP TABLE Cards;
SQL error: no such table: Cards
sqlite> .read datos.sql
sqlite> .output insert.sqlite
sqlite> .dump
sqlite>

El nombre del archivo se puede cambiar, pero da lo mismo, porque aun no tenemos la base de datos, pero ya solo queda un último paso, que es:
sqlite cartasMagic.db < insert.sqlite

Una pega que tiene esto, es que el archivo mdb ocupaba 7 megas y el sqlite ocupa 25.

Ya esta, ahora solo queda demostrar que podemos ejecutar consultas sql, por ejemplo vamos a buscar las cartas que se llamen Fireball y sean de quinta edición:
josu@cyrusnet:~/downloads$ sqlite cartasMagic.db "SELECT * FROM Cards WHERE Edition='5E' AND Name ='Fireball'"

Resultado:
Fireball|R|C|5E||0.8300|Sorcery|XR|Mark Tedin|Pay <1> for each target beyond the first: Fireball deals X damage divided evenly, rounded down, among any number of target creatures and/or players.||||5E\Fireball.jpg|1||NF

Para terminar: No es necesario ejecutar las consultas desde bash, hay módulos de sqlite para C++, php, python, etc. Existe el programa kexi que en principio nos hace todo esto mucho más rápido, pero lo he instalado y no me ha funcionado, se cerraba solo por algún bug, así que la forma que hemos visto aquí sirve siempre.

No hay comentarios:

Publicar un comentario