• Publicidad

Importar Excel a base de datos usando un archivo ".tabs"

Todo acerca de las bases de datos que existen: SQL, MySQL, Oracle, Postgres, CSV, etc.

Importar Excel a base de datos usando un archivo ".tabs"

Notapor Alfumao » 2011-06-06 05:43 @280

Buenos días,

Necesito pasar la información de una tabla Excel a una base de datos en MySQL.

Para ello he modificado un script publicado por James Tisdall que permite realizar dicho proceso convirtiendo la tabla Excel a un archivo ".tabs" como el adjunto.

En teoría se conseguiría con el script que os pongo, pero resulta que no hay manera y me estoy volviendo loco.

Os agradecería sugerencias y/o modificaciones bien en el script o en el formato de archivo al que convertir el Excel.

Necesito conseguir este paso lo antes posible para no perder muchos meses de trabajo.

Aquí va el script que publicó J. Tisdall y yo modifiqué:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!c:/perl/bin/perl.exe
  2. use warnings;
  3. use strict;
  4.  
  5. # Make connection with MySQL database
  6.  
  7. use DBI;
  8.  
  9. my $database = 'fungo';
  10. my $server = 'localhost';
  11. my $user = 'root';
  12. my $passwd = 'password';
  13.  
  14. my $homologs = DBI->connect("dbi:mysql:$database:$server", $user, $passwd);
  15. my $sqlinit = $homologs->prepare("show tables");
  16. $sqlinit->execute();
  17. while (my $row = $sqlinit->fetchrow_arrayref) {
  18.         print join("\t", @$row), "\n";
  19. }
  20.  
  21. my $flag = 0;
  22. my $table;
  23. my @tables;
  24. my $sql;
  25.  
  26. while(<>) {
  27.     # skip blank lines
  28.     if(/^\s*$/) {
  29.         next;
  30.  
  31.     # begin new table
  32.     }elsif(/^TABLE\t(\w+)/) {
  33.         $flag = 1;
  34.         $table = $1;
  35.         push(@tables, $table);
  36.         # Delete all rows in database table
  37.         my $droprows = $homologs->prepare("delete from $table");
  38.         $droprows->execute();
  39.  
  40.     # get fieldnames, prepare SQL statement
  41.     } elsif($flag == 1) {
  42.         $flag = 2;
  43.         my @fieldnames = split;
  44.         my $query = "insert into  $table (" . join(",", @fieldnames) . ") values (" . "?, " x (@fieldnames-1) . "?)";
  45.         $sql = $homologs->prepare($query);
  46.  
  47.     # get row, execute SQL statement
  48.     } elsif($flag == 2) {
  49.         my @fields = split;
  50.         $sql->execute( @fields);
  51.     }
  52. }
  53.  
  54. # Check if tables were updated
  55.  
  56. foreach my $table (@tables) {
  57.         print "\nTable: $table\n\n";
  58.         my $query = "select * from $table";
  59.         my $sql = $homologs->prepare($query);
  60.         $sql->execute();
  61.  
  62.         while (my $row = $sql->fetchrow_arrayref) {
  63.             print join("\t", @$row), "\n";
  64.         }
  65. }
  66.  
  67. # Break connection with MySQL database
  68.  
  69. $homologs->disconnect;
  70.  
  71. exit;
  72.  
  73.  
  74.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Y este seria un ejemplo de archivo ".tabs" obtenido del Excel:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
TABLE OXTRY
Organism Ndufs1 Ndufs2 Ndufs3 Ndufs4 Ndufs6 Ndufs7 Ndufs8
NCR NCU01765 NCU02534   NCU04074 NCU05221 NCU00484 NCU03953 NCU05009
FOX FOXG_07987 FOXG_00680 FOXG_06006 FOXG_10434 FOXG_01910 FOXG_05196 FOXG_04085
FGR FGSG_05198 FGSG_00376 FGSG_09234 FGSG_02474 FGSG_06909 FGSG_10276 FGSG_07867
FVE FVEG_04906 FVEG_00831 FVEG_03873 FVEG_09088 FVEG_14032 FVEG_03763 FVEG_07199
AFU Afu5g04370 Afu2g13710 Afu6g08810 None Afu5g02080 Afu4g05860 Afu1g06610
HCA HCAG_06929 HCAG_04623 HCAG_05764 HCAG_00972  HCAG_00338 HCAG_03991 HCAG_05509
DHA DEHA0G06721g DEHA0F11077g DEHA0A12265g DEHA0F22154g DEHA0B11770g DEHA0F02838g DEHA0D03652g
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4



El programa Perl, si se llama tabla.load, según las instrucciones del autor, debería ejecutarse de la siguiente forma:

%perl tabla.load homologs.tabs

Yo lo ejecuto colocándolo en la carpeta

"c:\perl\bin"

¿Puede ser que lo esté ejecutando mal además del problema del formato?

Ojalá podáis ayudarme, alguien ;)
Alfumao
Perlero nuevo
Perlero nuevo
 
Mensajes: 178
Registrado: 2009-12-10 11:20 @514

Publicidad

Re: Importar Excel a base de datos usando un archivo ".tabs"

Notapor explorer » 2011-06-06 06:04 @294

Bueno, este código no hace la transformación de Excel a formato tabs, sino que hace la parte de pasar del formato .tabs a la base de datos.

Por lo que veo, el programa parece que está bien. Lo único curioso, es que en la línea 32 dice que espera que la línea, dentro del tabs, que comience por TABLE, debe estar separada por el nombre de la tabla por un carácter tabulador. Y en el ejemplo que has puesto, me parece que no lo hay.

Yo cambiaría el '\t' por un '\s+'.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Importar Excel a base de datos usando un archivo ".tabs"

Notapor Alfumao » 2011-06-06 07:35 @358

Hola explorer,

He modificado la línea 32 como me dijiste, y he descargado de la página de J.Tisdall el archivo .tabs que tiene de ejemplo y que escribo bajo estas líneas:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
TABLE   ORGANISM
OrgId   Organism
1       human
2       worm
3       mouse

TABLE   GENES
GeneId  Gene    Date
118     aging   1984-07-13
9223    wrinkle 1987-08-15
273     hairy   1990-09-30

TABLE   VARIANTS
VarId   OrgId   GeneId
1       1       118
2       2       118
3       1       9223
4       3       9223
5       3       273
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Aún usando este archivo no consigo que el programa me cree una base de datos en el MySQL de XAMPP.

¿Podría estar el fallo en la forma de ejecutarlo según las instrucciones que expuse en la primera entrada del post?

El programa Perl, si se llama tabla.load, según las instrucciones del autor, debería ejecutarse de la siguiente forma:

%perl tabla.load homologs.tabs

Yo lo ejecuto colocándolo en la carpeta

"c:\perl\bin"


Lo único que consigo es que me liste en pantalla las tablas de la base de datos a la que accedo, pero no me modifica ni me crea nada...

Te pregunto esto porque ya no sé qué más vueltas darle al formato para intentar que funcione...

¿Crees que habría una opción alternativa que me permita conseguir el resultado que busco de una forma menos complicada? (Digo esto porque quizá haya una vía más sencilla y yo estoy tan empecinado con hacer funcionar esta, que sólo pierdo tiempo y posiblemente acabe perdiendo hasta la oportunidad de usar los datos que recopilé en el Excel...)

Muchas gracias por tu atención y tu rapidez contestando, explorer ;)
Alfumao
Perlero nuevo
Perlero nuevo
 
Mensajes: 178
Registrado: 2009-12-10 11:20 @514

Re: Importar Excel a base de datos usando un archivo ".tabs"

Notapor explorer » 2011-06-06 08:13 @384

El programa no crea ninguna base de datos.

Lo que hace es leer el fichero de entrada, línea a línea, y cuando encuentra una línea TABLE, manda una orden de borrar la tabla correspondiente dentro de la base de datos. Y las siguientes líneas hace un INSERT por cada una de ellas.

Eso quiere decir...

* que la base de datos debe estar creada antes
* que la base de datos debe tener definidas y creadas, las tablas

Este último paso es también importante: este programa tampoco crea las tablas. Tienes que crearlas antes de arrancar el programa.

En caso de error, debes sacar el valor de $DBI::errstr para saber qué ha pasado. Pon la opción RaiseError => 1 en el new del DBI, para que saque un error en pantalla, parando el programa. Así tendremos más pistas.

Por ejemplo, en las líneas 38 y 50 no se comprueba si ha ocurrido un error.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Importar Excel a base de datos usando un archivo ".tabs"

Notapor Alfumao » 2011-06-06 08:35 @399

Hola de nuevo,

Por lo que yo entendía, si tenía una base de datos creada, con una tabla creada, este programa podía coger dicha tabla y reemplazar sus datos con los datos del archivo .tabs (borrando los datos prexistentes, antes de correr el programa).

Ahora viendo lo que me explicas,
¿La tabla que debe estar creada, ha de ser exactamente igual en cuanto a características que la que crea el programa? Es decir, tener el mismo número de filas y columnas con variables de iguales características.

Si esto es así, entonces, ¿hay una forma de pasar un Excel a MySQL vía Perl, que no me obligue a tener que introducir manualmente (o mediante sentencias insert individualizadas para cada línea) todas las variables?

La tabla que he de manejar tiene miles de celdas y sería inviable hacerlo de forma manual en el plazo de tiempo del que dispongo...
Alfumao
Perlero nuevo
Perlero nuevo
 
Mensajes: 178
Registrado: 2009-12-10 11:20 @514

Re: Importar Excel a base de datos usando un archivo ".tabs"

Notapor explorer » 2011-06-06 09:07 @422

Te basta con que la tabla tenga el mismo número de columnas (campos) que las que vas a insertar. Y deben llamarse igual que la primera fila de datos (la cabecera de campos, la que sigue a TABLE). En cuanto al tipo de dato de cada columna, te vale con que sean strings o varchar, ya que el programa no distingue lo que está leyendo (quiero decir que Perl está enviando strings hacia la base de datos).

En cuanto a si esto se puede automatizar: sí.

Te vale con modificar las líneas 36 a 39 para agregar sentencias SQL del tipo CREATE TABLE en caso de que la tabla no exista, para crearla dentro de MySQL.

Luego, una vez creada la tabla, se supone que todas las líneas de datos serán iguales (en cuanto a número de campos), y el INSERT de la línea 44 hará su trabajo.

Atención al caso de que tengas una línea al que le falte un campo (la celda correspondiente esté vacía). En la línea 49 hay un split(), que está dividiendo la línea por los espacios en blanco que separa a esos campos. Si a la línea que estás leyendo le falta un campo, entonces el INSERT fallará porque le estás pasando menos campos que los que espera la sentencia creada en la línea 44. Si sospechas que puede ocurrir ese caso, tendrás que contemplarlo en la línea 49 (ver si el número de @fields es igual al de @fieldnames sacados en la línea 43). Esto se podría solventar, si el fichero tabs mantiene los campos separados por un tabulador, por ejemplo.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Importar Excel a base de datos usando un archivo ".tabs"

Notapor Alfumao » 2011-06-06 09:37 @442

Gracias explorer,

La tabla no tiene celdas en blanco, ya que las que pudieran estar vacías tienen escrito "None", así que eso no sería un problema en principio.
Alfumao
Perlero nuevo
Perlero nuevo
 
Mensajes: 178
Registrado: 2009-12-10 11:20 @514

Re: Importar Excel a base de datos usando un archivo ".tabs"

Notapor Alfumao » 2011-06-07 05:23 @266

Hola de nuevo explorer,

He hecho la modificación que he hecho en las lineas 36-39 en base a lo que me comentaste.
¿Era esto a lo que te referías?

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!c:/perl/bin/perl.exe
  2. use warnings;
  3. use strict;
  4.  
  5. # Make connection with MySQL database
  6.  
  7. use DBI;
  8.  
  9. my $database = 'fungo';
  10. my $server = 'localhost';
  11. my $user = 'root';
  12. my $passwd = 'password';
  13.  
  14. my $homologs = DBI->connect("dbi:mysql:$database:$server", $user, $passwd);
  15. my $sqlinit = $homologs->prepare("show tables");
  16. $sqlinit->execute();
  17. while (my $row = $sqlinit->fetchrow_arrayref) {
  18.         print join("\t", @$row), "\n";
  19. }
  20.  
  21. my $flag = 0;
  22. my $table;
  23. my @tables;
  24. my $sql;
  25.  
  26. while(<>) {
  27.     # skip blank lines
  28.     if(/^\s*$/) {
  29.         next;
  30.  
  31.     # begin new table
  32.     }elsif(/^TABLE\t(\w+)/) {
  33.         $flag = 1;
  34.         $table = $1;
  35.         push(@tables, $table);
  36. # Delete all rows in database table
  37. #        my $droprows = $homologs->prepare ("delete from $table");
  38. #        $droprows->execute();
  39.  if (!$1){
  40.  my $dotable = $homologs->prepare("create $table");
  41.     $dotable->execute();
  42.         $flag = 1;
  43.  }
  44.        
  45.     # get fieldnames, prepare SQL statement
  46.     } elsif($flag == 1) {
  47.        $flag = 2;
  48.        my @fieldnames = split;
  49.        my $query = "insert into  $table (" . join(",", @fieldnames) . ") values (" . "?, " x (@fieldnames-1) . "?)";
  50.         $sql = $homologs->prepare($query);
  51.  
  52.     # get row, execute SQL statement
  53.     } elsif($flag == 2) {
  54.         my @fields = split;
  55.         $sql->execute( @fields);
  56.     }
  57. }
  58.  
  59. # Check if tables were updated
  60.  
  61. foreach my $table (@tables) {
  62.         print "\nTable: $table\n\n";
  63.         my $query = "select * from $table";
  64.         my $sql = $homologs->prepare($query);
  65.         $sql->execute();
  66.  
  67.         while (my $row = $sql->fetchrow_arrayref) {
  68.             print join("\t", @$row), "\n";
  69.         }
  70. }
  71.  
  72. # Break connection with MySQL database
  73.  
  74. $homologs->disconnect;
  75.  
  76. exit;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
Alfumao
Perlero nuevo
Perlero nuevo
 
Mensajes: 178
Registrado: 2009-12-10 11:20 @514

Re: Importar Excel a base de datos usando un archivo ".tabs"

Notapor explorer » 2011-06-07 05:30 @271

El proceso CREATE TABLE hay que hacerlo cuando no exista la tabla en la base de datos. No tiene sentido preguntar si $1 tiene un valor verdadero o no.

En la línea 15 se leen las tablas de la base de datos, así que ahí podrías quedarte con sus nombres, y luego, en la línea 36, si el nombre de la tabla que el fichero tabs solicita usar, no existe entre las que has leído (ergo, no existe en la base de datos), entonces es cuando debes realizar el proceso de CREATE TABLE con el nombre de la tabla a crear y los nombres de las columnas (campos) que esa tabla debe tener.

Intenta hacer un programa, aparte, que haga solo eso: crear una tabla con una definición de los campos. Cuando funcione, agrega el código al programa principal.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Importar Excel a base de datos usando un archivo ".tabs"

Notapor Alfumao » 2011-06-09 04:11 @216

Una cosilla, explorer,

Verás, es que me estoy haciendo un lío muy gordo. Yo pensaba que el problema era del formato del archivo de entrada (.tabs). Imaginaba que el programa no lo podía leer y por eso no hacía lo que se esperaba de él. La tabla que quiero meter en la base de datos sería siempre con el mismo nombre, pero solo cambiarían el número de filas y quizá el de columnas.

Lo que tu me comentas está enfocado para crear una tabla si no la hay, eso lo entiendo, pero en este caso, que sí la hay (con el mismo nombre) ¿No se supone que el programa original habría de borrar línea a línea, una tabla que ya estuviera presente en la base de datos y reemplazarla, creando una nueva con su mismo nombre pero con las nuevas características derivadas de los datos del archivo ".tabs"?

Se supone que el borrado lo haría así, ¿no?

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. # Delete all rows in database table
  2.        my $droprows = $homologs->prepare ("delete from $table");
  3.        $droprows->execute();
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Y ya después el propio programa va insertando los campos y los valores, de esta forma, ¿no?

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.   elsif($flag == 1) {
  2.        $flag = 2;
  3.        my @fieldnames = split;
  4.        my $query = "insert into  $table (" . join(",", @fieldnames) . ") values (" . "?, " x (@fieldnames-1) . "?)";
  5.         $sql = $homologs->prepare($query);
  6.  
  7.     # get row, execute SQL statement
  8.     } elsif($flag == 2) {
  9.         my @fields = split;
  10.         $sql->execute( @fields);
  11.     }
  12. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


No sé sí estoy empezando a perder el objetivo original de mi pregunta y al final acabo formando un lío de narices...

En fin, muchísimas gracias por tu atención, explorer.
Alfumao
Perlero nuevo
Perlero nuevo
 
Mensajes: 178
Registrado: 2009-12-10 11:20 @514

Siguiente

Volver a Bases de datos

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 2 invitados