• Publicidad

Incorporar texto estructurado a una BD

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Notapor kidd » 2006-03-31 13:07 @588

preiddy escribiste:Ok, gracias por la respuesta. Pero ahora me surge otra duda: si en el sql digo o declaro campo "x" y luego no se le pasa ningún valor, ¿no dará error?

Depende de cómo declares el campo. Si lo pones que puede ser NULL el valor entonces no hay problema.

Ahora te recomiendo que leas en el manual de MySQL acerca de los campos NULL:

http://dev.mysql.com/doc/refman/4.1/en/ ... -null.html

Saludos
Uriel Lizama Perl programmer fundador de Perl en Español
Perl Programming Language
Avatar de Usuario
kidd
Creador de Perl en Español
Creador de Perl en Español
 
Mensajes: 1166
Registrado: 2003-10-15 16:52 @744
Ubicación: México

Publicidad

Notapor preiddy » 2006-04-01 03:53 @203

Hola de nuevo, y gracias por las respuestas.

La solución dada por explorer es fenomenal. Ahora bien, como el objetivo final es aprender tengo unas dudas con el script, y claro, si pueden ser aclaradas lo agradezco enormemente.

my $base = do { local $/; open(BASE,"<pubmed-result.txt"); <BASE> };

Esta forma de recorrer un archivo es nueva para mi, siempre lo he hecho con while, ¿qué facilidades o ventajas ofrece hacerlo así?

my ($valor) = $registro =~ /^$campo_actual (.+?)^$campo_siguiente */ms;

Esta expresión regular me dejó ya fuera, ¡ja,ja! Pero es el punto fuerte del script, ¿cómo se extrae el valor?

Si se tiene un archivo de texto con una estructura similar al expuesto en mensajes anteriores, donde cada registro va en una línea, solo con cambiarle las marcas sería suficiente para que pueda ser analizado, o eso es lo que creía, pero al hacerlo me imprime algo totalmente diferente a lo que esperaba. El archivo es así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
PMID- 16571888
OWN - NLM
STAT- In-Process
DA  - 20060330
PUBM- Print
IS  - 1533-4406 (Electronic)
VI  - 354
IP  - 13
DP  - 2006 Mar 30
TI  - Lethal avian influenza A (H5N1) infection in a pregnant woman in Anhui
      Province, China.
PG  - 1421-2
FAU - Shu, Yuelong
AU  - Shu Y
FAU - Yu, Hongjie
AU  - Yu H
FAU - Li, Dexin
AU  - Li D
LA  - eng
PT  - Letter
PL  - United States
TA  - N Engl J Med
JT  - The New England journal of medicine.
JID - 0255562
SB  - AIM
SB  - IM
EDAT- 2006/03/31 09:00
MHDA- 2006/03/31 09:00
AID - 354/13/1421 [pii]
AID - 10.1056/NEJMc053524 [doi]
PST - ppublish
SO  - N Engl J Med. 2006 Mar 30;354(13):1421-2.

PMID- 16571885
OWN - NLM
STAT- In-Process
DA  - 20060330
PUBM- Print
IS  - 1533-4406 (Electronic)
VI  - 354
IP  - 13
DP  - 2006 Mar 30
TI  - Vaccines against avian influenza--a race against time.
PG  - 1411-3
FAU - Poland, Gregory A
AU  - Poland GA
LA  - eng
PT  - Comment
PT  - Editorial
PL  - United States
TA  - N Engl J Med
JT  - The New England journal of medicine.
JID - 0255562
SB  - AIM
SB  - IM
EDAT- 2006/03/31 09:00
MHDA- 2006/03/31 09:00
AID - 354/13/1411 [pii]
AID - 10.1056/NEJMe068047 [doi]
PST - ppublish
SO  - N Engl J Med. 2006 Mar 30;354(13):1411-3.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
Donde PMID y SO se pueden tomar como inicio y final de campo, hago el respectivo cambio en la línea:

while ( $base =~ /(^PMID.+?^SO.+?)/smg )

ejecuto y esto es lo que imprime:
Sintáxis: [ Descargar ] [ Ocultar ]
Using sql Syntax Highlighting
  1. INSERT todo SET  own = "- NLM
  2. STAT- In-Process
  3. DA  - 20060330
  4. PUBM- Print
  5. IS  - 1533-4406 (Electronic)
  6. VI  - 354
  7. IP  - 13
  8. DP  - 2006 Mar 30
  9. TI  - Lethal avian influenza A (H5N1) infection in a pregnant woman in Anhui
  10.      Province, China.", IS = " - 1533-4406 (Electronic)
  11. VI  - 354
  12. IP  - 13
  13. DP  - 2006 Mar 30
  14. TI  - Lethal avian influenza A (H5N1) infection in a pregnant woman in Anhui
  15.      Province, China.
  16. PG  - 1421-2
  17. FAU - Shu, Yuelong
  18. AU  - Shu Y
  19. FAU - Yu, Hongjie
  20. AU  - Yu H
  21. FAU - Li, Dexin
  22. AU  - Li D
  23. LA  - eng
  24. PT  - Letter
  25. PL  - United States
  26. TA  - N Engl J Med
  27. JT  - The New England journal of medicine.", dp = " - 2006 Mar 30
  28. TI  - Lethal avian influenza A (H5N1) infection in a pregnant woman in Anhui
  29.      Province, China.
  30. PG  - 1421-2", pt = " - Letter
  31. PL  - United States
  32. TA  - N Engl J Med
  33. JT  - The New England journal of medicine.
  34. JID - 0255562
  35. SB  - AIM
  36. SB  - IM
  37. EDAT- 2006/03/31 09:00
  38. MHDA- 2006/03/31 09:00
  39. AID - 354/13/1421 [pii]
  40. AID - 10.1056/NEJMc053524 [doi]
  41. PST - ppublish", pg = " - 1421-2
  42. FAU - Shu, Yuelong
  43. AU  - Shu Y
  44. FAU - Yu, Hongjie
  45. AU  - Yu H
  46. FAU - Li, Dexin
  47. AU  - Li D
  48. LA  - eng
  49. PT  - Letter", da = " - 20060330
  50. PUBM- Print
  51. IS  - 1533-4406 (Electronic)
  52. VI  - 354
  53. IP  - 13", pl = " - United States
  54. TA  - N Engl J Med
  55. JT  - The New England journal of medicine.
  56. JID - 0255562
  57. SB  - AIM
  58. SB  - IM
  59. EDAT- 2006/03/31 09:00
  60. MHDA- 2006/03/31 09:00
  61. AID - 354/13/1421 [pii]
  62. AID - 10.1056/NEJMc053524 [doi]";
  63. ########################################
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Solo quería ver como lo imprimía, y después de darle varias vueltas al script para tratar de ajustarlo a este nueva estructura, detecté que esta variante de archivo duplica las marcas de los campos cuando tiene más de un valor, es decir, por cada autor le asigna al comienzo la marca AU.

¿Esa duplicidad de marcas puede tener algo que ver con que no reconoce o procesa correctamente el archivo?

Por último y con esto dejo de dar la lata, este nuevo archivo lo puedo obtener en XML, pero con menos datos que uno de txt, ¿existe una librería de Perl que pase directamente del xml a base de datos? Porque lo que sí he visto es de base de datos a XML.

Bueno, de nuevo, gracias. :D
preiddy
Perlero nuevo
Perlero nuevo
 
Mensajes: 70
Registrado: 2006-03-29 05:43 @280
Ubicación: Madrid, España

Re: Incorporar texto estructurado a una BD

Notapor explorer » 2006-04-01 06:16 @303

preiddy escribiste:my $base = do { local $/; open(BASE,"<pubmed-result.txt"); <BASE> };

¿qué facilidades o ventajas ofrece hacerlo así?
Con while es fácil de entender y de usar y es la forma recomendada, ya que a veces trabajamos con ficheros enormes que no caben en memoria, por lo que es normal leer línea a línea y trabajar con cada una.

En el caso de que el fichero sí entre en memoria -y tengamos que trabajar con todo él-, entonces hay varias opciones para leerlo completamente (si ese es nuestro deseo). Una de ellas es la mostrada: indefinimos el separador de registros de entrada $/ (por defecto vale lo mismo que un '\n' del sistema) -esto quiere decir que... en realidad el fichero que vamos a leer... NO tiene registros... que es lo mismo que decir que... nos lo vamos a leer todo de una sola vez-; luego lo abrimos con open() y luego lo leemos con '<>'. De esta forma leemos el fichero a una variable e$calar.

Otra forma es esta:

my @base = do { open(BASE,"<pubmed-result.txt"); <BASE> };

Es casi lo mismo, pero no... aquí abrimos el fichero de forma normal y... ejecutamos la lectura del fichero con '<>'. El operador diamante por defecto funciona en contexto de lista, por lo que devolverá un array con todos los valores (líneas) del fichero, que quedará asignado a nuestra @rray.

How can I read in an entire file all at once? slurp file, slurping.

preiddy escribiste:my ($valor) = $registro =~ /^$campo_actual (.+?)^$campo_siguiente /ms;

¿cómo se extrae el valor?
Queda claro que $campo_actual y $campo_siguiente son los campos que estamos buscando -bueno, en realidad queremos lo que está entre los dos-. Cada uno de ellos contienen dos letras en mayúscula.

La expresión regular entonces quiere decir: "Busca (=~) en $registro aquella línea -pues contiene más de una (/m)-, que comienza (^) por nuestro $campo_actual, seguido de un espacio en blanco, seguido por un conjunto de caracteres (.+) -incluido el retorno de carro (/s)-, pero lo menos posible (?) para llegar a la siguiente línea que empieza (^) por el $campo_siguiente seguido de un espacio en blanco. Devuelve el conjunto de caracteres encontrados (()) a la variable $1.

Pero como el usuario nos pide un array (($valor)), también lo devolvemos como primer valor de ese array".

preiddy escribiste:Si se tiene un archivo de texto con una estructura similar al expuesto en mensajes anteriores, donde cada registro va en una linea, solo con cambiarle los tag seria suficiente para que pueda ser analizado, o eso es lo que creía, pero al hacerlo me imprime algo totalmente diferente a lo que esperaba.
En el programa que te mandé hay que hacer varios cambios, entonces:
  1. @campos debe contener los campos que hay dentro del registro Y en el orden en que aparecen
  2. %campos debe contener la correspondencia de esos campos a los de la base de datos
  3. En el while, indicar los campos inicio y fin de registro.

preiddy escribiste:Donde PMID y SO se pueden tomar como inicio y final de campo, hago el respectivo cambio en la línea:

while ( $base =~ /(^PMID.+?^SO.+?)/smg )

ejecuto y esto es lo que imprime:
No importa el tamaño de los campos (2 o 4 letras), lo importante es el orden en que están escritos en @campos.

preiddy escribiste:Solo quería ver cómo lo imprimía, y después de darle varias vueltas al script para tratar de ajustarlo a este nueva estructura, detecté que esta variante de archivo duplica las marcas de los campos cuando tiene más de un valor, es decir, por cada autor le asigna al comienzo la marca AU -. ¿Esa duplicidad de marca puede tener algo que ver con que no reconoce o procesa correctamente el archivo?
Pues sí. El problema es completamente distinto. Si son pocos campos que hacen la duplicidad, entonces hay que plantearlo desde otro punto de vista.

Quizás entonces lo más cómodo es volver a recorrer el registro línea a línea e ir almacenando valores con el mismo valor de campo. Luego, sigue igual que antes a la hora de crear la sentencia sql.

preiddy escribiste:Por último y con esto dejo de dar la lata, este nuevo archivo lo puedo obtener en XML, pero con menos datos que uno de txt, ¿existe una librería de perl que pase directamente del xml a base de datos? Porque lo que sí he visto es de base de datos a xml.
Directamente, creo que no, pero con los módulos XML::Simple y XML::Twig (sobre todo este último) te pueden ayudar bastante.

De todas formas, hay módulos como AnyData::Format::XML que manejan los xml como si fueran bases de datos, por lo que es más fácil aún el pasarles a otra base de datos (incluso no pasarles :) ).

Actualización: Entra en XML::RDB y busca por 'A Sample Run using MySQL'.
Sí que hay módulos... sólo es cuestión de buscarlos :)
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Anterior

Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado