Para los que todos los dias tenemos que trabajar con bash en nuestros sistemas, ya sea como administradores de sistemas, desarrolladores, etc. sabemos lo importante que es para nosotros la linea de comandos, y que mejor si podemos aprender algunos trucos para agilizar ese trabajo, asi aqui les presento un par de ellos:
ctrl+r: Bash registra cada uno de los comandos que ejecutamos en una bitacora, y esta nos permite regresar a ellos cuando los necesitamos u olvidamos los parametros de un determinado comando que tanto trabajo nos costo construir; una de las formas de hacer esto es mediante las teclas de flecha hacia arriba y abajo, lo cual nos lleva a los comandos ingresados con anterioridad y navegar a travez de ellos. Pero si necesitamos encontrar el comando con mayor rapidez, podemos hacer uso de la busqueda rapida, esta busca entre los comandos ingresados aquellos que inician con las letras que ingresamos luego de la combinacion de teclas ctrl+r, Bash comenzara una busqueda y nos mostrara aquellos comandos que coinciden con las letras que estamos ingresando; si el comando mostrado no es el que estamos buscado, podemos seguir presionando ctrl+r para ir al siguiente resultado de la busqueda y asi sucesivamente; una vez encontrado el comando deseado, damos enter para ejecutarlo inmediatamente o las teclas de flechas izquierda o derecha para editarlo, en caso que deseamos editar la linea antes de ejecutarla.
!! y !#
Este es otro par de combinacion de simbolos que permiten agilizar nuestras actividades en Bash, el primero !! nos permite ejecutar exactamente el comando ingresado anteriormente. En cuanto al segundo, este nos permite ejecutar el comando #, donde el numero especificado es el numero asignado por la secuencia del comando history.
Por ejemplo, si al ejecutar el comando history, vemos el siguiente resultado: (salida ha sido truncada)
44 history
45 cd Backup/
46 history
47 yum
48 #?
Al ejecutar !45 equivale a ejecutar nuevamente el comando: cd Backup/
Pregunta: que almacena Bash en la variable denominada $?
Si conoces otros trucos de la linea de comandos, compartelos.
Aqui habra de todo, bueno, espero tener tiempo para tanto, pero pienso escribir sobre la familia, tecnologia, actualidad, etc. En fin de todo un poco, pero como dije, espero. Hasta pronto.
Wednesday, May 19, 2010
Wednesday, May 12, 2010
Ayer Pascal, C, Python, ahora Ruby, manana Go?
Lejos ha quedado la epoca en que daba clases de Teoria de Lenguajes de Programacion alla por el 96-99 para la carrera de computacion en la UCA, donde hablabamos de los automatas finitos, analizadores lexicos/sintacticos, expresiones regulares, etc, atras ha quedado la epoca en que usabamos el compilador Turbo C/Pascal de Borland, o Modula-2 para quienes programaron en ese lenguaje, ahora los lenguajes son orientados a objetos, paradigma que comenzaba a despegar por aquellos anios en El Salvador, pocos eran los que intentaban descifrar de que se trataba, pero que ahora es un elemento indispensable en los nuevos y modernos lenguajes de programacion, asi como una herramienta indispensable para los programadores actualmente. Lisp se podria decir que era de los lenguajes mas avanzados a su epoca, utilizado primordialmente en sistemas de Inteligencia Artificial (al igual que Prolog), tenia problemas de eficiencia (no se si culpar a la recursividad por tal razon) asi como no era facil tratar de resolver cualquier problema de la vida real mediante formulas matematicas y recursividad; Pascal y Basic digamos que eran los lenguajes que nos motivaron a estudiar computacion, ensamblador fue el que nos hizo lograr entender como los circuitos digitales dentro de la computadora colaboran entre ellos en una sincronia de reloj, para calcular la serie de Fibonacci, buscar numeros primos o simplemente resolver una ecuacion de segundo grado. Finalmente C, era como la llave a todas nuestras respuestas, el problema era como usar la llave, siendo un lenguaje de alto-medio nivel, dispone de gran habilidad para desarrollar programas en casi cualquier rama, por eso se le denomina lenguaje de proposito general, como tambien estar lo suficientemente cerca del hardware para ser eficiente y descubrir los secretos del BIOS y cambiar el vector de interrupciones de la computadora (para los que haciamos programas residentes en memoria o TSR(Terminate and Stay Resident ).
Se acuerdan de los lenguajes de cuarta generacion, pues si no se acuerdan de ellos es por que nunca los conocieron o trabajaron en ellos, originalmente desarrollados con el fin de resolver un grupo en particular de problemas, (principalmente en el ambito de los negocios y reemplazar al omnipresente COBOL), tenemos a PowerBuilder, Natural, entre otros, que durante algun tiempo se creia eran la respuesta a los sistemas empresariales, cuando aparecio el Internet; HTML (aun que no un lenguaje de programacion), pero que gano popularidad con el advenimiento del Internet y las paginas web y el Dot Com; Java, JavaScript, PHP, Perl son otros de los grandes protagonistas de las nuevas generaciones de aplicaciones que poblarian la red en los anios venideros uniendo fuerzas con bases de datos como MySQL/PostgreSQL.
Actualmente, la lista de lenguajes de programacion es enorme y llena de todo tipo de lenguajes destinados a una gran gama de posibles probemas de la vida cotidiana o no tan cotidiana, en los ultimos 3 anios Python se ha ajustado muy bien en cubrir las necesidades que require mi trabajo de control de calidad de software, automatizando pruebas de software, pero actualmente la empresa donde trabajo, el lenguaje que mas utilizan es Ruby, de hecho una de las librerias que utlizamos para hacer pruebas esta en ese lenguaje, asi que aqui me tienen leyendo/aprendiendo un poco de Ruby en un rato que tengo libre en el trabajo, eso significa otro lenguaje a la bolsa, no esta nada mal, pero luego de Ruby que? Erlang? Go? Nimrod? Ioke?
Y ustedes en que lenguaje programan/crean scripts?
Saludos.
Se acuerdan de los lenguajes de cuarta generacion, pues si no se acuerdan de ellos es por que nunca los conocieron o trabajaron en ellos, originalmente desarrollados con el fin de resolver un grupo en particular de problemas, (principalmente en el ambito de los negocios y reemplazar al omnipresente COBOL), tenemos a PowerBuilder, Natural, entre otros, que durante algun tiempo se creia eran la respuesta a los sistemas empresariales, cuando aparecio el Internet; HTML (aun que no un lenguaje de programacion), pero que gano popularidad con el advenimiento del Internet y las paginas web y el Dot Com; Java, JavaScript, PHP, Perl son otros de los grandes protagonistas de las nuevas generaciones de aplicaciones que poblarian la red en los anios venideros uniendo fuerzas con bases de datos como MySQL/PostgreSQL.
Actualmente, la lista de lenguajes de programacion es enorme y llena de todo tipo de lenguajes destinados a una gran gama de posibles probemas de la vida cotidiana o no tan cotidiana, en los ultimos 3 anios Python se ha ajustado muy bien en cubrir las necesidades que require mi trabajo de control de calidad de software, automatizando pruebas de software, pero actualmente la empresa donde trabajo, el lenguaje que mas utilizan es Ruby, de hecho una de las librerias que utlizamos para hacer pruebas esta en ese lenguaje, asi que aqui me tienen leyendo/aprendiendo un poco de Ruby en un rato que tengo libre en el trabajo, eso significa otro lenguaje a la bolsa, no esta nada mal, pero luego de Ruby que? Erlang? Go? Nimrod? Ioke?
Y ustedes en que lenguaje programan/crean scripts?
Saludos.
El archivo /etc/passwd
Los que trabajamos en sistemas Unix/Linux sabemos (espero) que este archivo contiene informacion sobre cada usuario que puede ingresar al sistema, el archivo tambien contiene, entre otros datos, la informacion necesaria para verificar la autenticidad del usuario, mediante la contrasenia, pero en algunos otros sistemas, esta informacion es transferida hacia otro archivo llamado /etc/shadow.
Este archivo puede ser leido por todos los usuarios, pero solamente el administrador o aquellos usuarios con permiso pueden editarlo.
El otro dia un amigo en el canal #linux.org.sv en IRC, preguntaba como podia hacer que un usuario al ingresar al sistema mediante ssh, solo pudiese tener acceso a una aplicacion en particular y si deseaba salirse de ella, al hacerlo, el sistema lo desconectaria inmediatamente; bueno la solucion estaba en el archivo /etc/passwd, si observamos bien en el archivo, el ultimo campo de cada linea corresponde al shell que atiende al usuario una vez este ingresa al sistema, pero que tal si en lugar de colocar el shell que atendera al usuario, colocamos el nombre y ubicacion de otro programa?, bueno este atendera al usuario mientras utilize el programa, pero una vez este termine de usarlo, el sistema lo desconecta automaticamente.
Veamos un ejemplo: Ojo, no intenten esto con su usuario, mi recomendacion es que creen un usuario de pruebas para hacerlo, pueden usar el siguiente comando en Linux, en el siguiente ejemplo usaremos el programa top, asi este usuario solo podra ver el resultado del comando top una vez ingrese al sistema:
$ sudo adduser -s /usr/bin/top testuser
Ahora asignemosle un password al usuario mediante:
$ sudo passwd testuser
Una vez el password ha sido asignado, observen la nueva linea en el archivo /etc/passwd y observen como la ultima columna en lugar de apuntar a un shell, apunta a /usr/bin/top; intentemos ingresar al sistema mediante este usuario, podemos usar el comando su:
$ su testuser
Una vez damos la contrasenia, en lugar de recibir un prompt ($) de un nuevo shell, vemos como el programa top inicia automaticamente, y cuando lo cancelamos mediante
la tecla "q", el usuario es automaticamente desconectado; para confirmarlo usamos el comando "whoami", debemos estar de regreso en nuestro usuario original y no el usuario de pruebas. Pueden confirmar esto tambien haciendo un 'tail -f' sobre el archivo /var/log/auth.log donde veran que el usuario sale al instante de cerrar top.
Que pasa si en lugar de /usr/bin/top cambian por /sbin/nologin?
Saludos.
Este archivo puede ser leido por todos los usuarios, pero solamente el administrador o aquellos usuarios con permiso pueden editarlo.
El otro dia un amigo en el canal #linux.org.sv en IRC, preguntaba como podia hacer que un usuario al ingresar al sistema mediante ssh, solo pudiese tener acceso a una aplicacion en particular y si deseaba salirse de ella, al hacerlo, el sistema lo desconectaria inmediatamente; bueno la solucion estaba en el archivo /etc/passwd, si observamos bien en el archivo, el ultimo campo de cada linea corresponde al shell que atiende al usuario una vez este ingresa al sistema, pero que tal si en lugar de colocar el shell que atendera al usuario, colocamos el nombre y ubicacion de otro programa?, bueno este atendera al usuario mientras utilize el programa, pero una vez este termine de usarlo, el sistema lo desconecta automaticamente.
Veamos un ejemplo: Ojo, no intenten esto con su usuario, mi recomendacion es que creen un usuario de pruebas para hacerlo, pueden usar el siguiente comando en Linux, en el siguiente ejemplo usaremos el programa top, asi este usuario solo podra ver el resultado del comando top una vez ingrese al sistema:
$ sudo adduser -s /usr/bin/top testuser
Ahora asignemosle un password al usuario mediante:
$ sudo passwd testuser
Una vez el password ha sido asignado, observen la nueva linea en el archivo /etc/passwd y observen como la ultima columna en lugar de apuntar a un shell, apunta a /usr/bin/top; intentemos ingresar al sistema mediante este usuario, podemos usar el comando su:
$ su testuser
Una vez damos la contrasenia, en lugar de recibir un prompt ($) de un nuevo shell, vemos como el programa top inicia automaticamente, y cuando lo cancelamos mediante
la tecla "q", el usuario es automaticamente desconectado; para confirmarlo usamos el comando "whoami", debemos estar de regreso en nuestro usuario original y no el usuario de pruebas. Pueden confirmar esto tambien haciendo un 'tail -f' sobre el archivo /var/log/auth.log donde veran que el usuario sale al instante de cerrar top.
Que pasa si en lugar de /usr/bin/top cambian por /sbin/nologin?
Saludos.
Friday, April 16, 2010
Que es Scratch?
Instrucciones para instalarlo en Linux: http://info.scratch.mit.edu/Linux_Installer
Wednesday, April 14, 2010
Llegaremos algun dia a colonizar Marte o una de las lunas de Saturno?
Es posible que con el avance cientifico de algunos paises y el desarrollo de nuevas tecnologias para viajar, una eventual colonizacion del planeta rojo sea una posibilidad viable en un futuro cercano (o no tan cercano?), la pregunta es, muy aparte de todas esas creencias de las personas en catastrofes y profesias que apuntan a una destruccion masiva (fin del mundo, 2012), las cuales han existido desde hace mucho y hasta ahora ninguna ha sido comprobada como cierta, pues mas se basan en la mera casualidad de eventos, la pregunta recae en: podremos los seres humanos como especie sobrevivir a nosotros mismos, a nuestras guerras, ambiciones, defectos, destruccion de nuestro propio habitat, y por encima de todo eso, lograr llegar a otro planeta o luna, y comenzar de nuevo?
Pero comenzar de nuevo, por suerte esta vez no tenemos que comenzar con herramientas rudimentarias como lo hicieron nuestros ancestros hace 65 millones de anios, sino que somos capaces de explicar de forma cientifica nuestro entorno, eso deberia darnos una ventaja abismal, y ser capaces de moldear este nuevo planeta en un habitat para seres humanos tal y como lo tenemos en nuestro globo terraqueo, en teoria.
Nuestro planeta se encuentra a la distancia exacta para que diversos procesos quimicos se desarrollen hasta el punto de crear seres multicelulares complejos, esto gracias a la existencia de agua en forma liquida, la orbita y rotacion estable del planeta, atmosfera y un campo magnetico que la protege de las inclemencias del sol; todos estos elementos contribuyen al sostenimiento de la vida en nuestro planeta, existe la posibilidad que semejantes combinaciones de elementos existan en otro punto del universo? Yo creo que si, pero el punto es que nuestra existencia aca esta limitada por la disponibilidad de elementos sostenedores de vida, o no?
En el caso de los dinosaurios, estos poblaban la tierra hasta hace unos 65 millones de anios, luego que segun la teoria del gran meteorito, acabo con ellos. Ese fue un evento totalmente fuera del control de los seres vivientes de esa epoca y podria ser nuestro caso tambien, ya paso una vez, volvera a pasar, cuando, quien sabe, pero para entonces es posible que ya hayamos encontrado la forma de habitar y adecuar otro planeta para nuestras necesidades, talvez para ese entonces, los cambios en el sol haran que en algun momento la distancia desde Marte hacia este, sea la distancia adecuada para el sostenimiento de vida tal y como la conocemos, haciendo de la Tierra solo un recuerdo y un planeta muy parecido a Venus, inhabitable.
El punto aqui es la perpetuidad de la especie humana, estamos aqui para quedarnos? lo dudo, la existencia del ser humano es tan solo un segundo si lo medimos en parametros desde la formacion del universo, pero lograremos perpetuar nuestra especie? me cuesta trabajo comprender que el ser humano, a pesar de todos sus defectos, desaparezca, y con el, todo el cumulo de informacion, tecnologia, arte, ciencias, etc. que hemos logrado desarrollar a lo largo de nuestra existencia. O es que el universo se empenia en volver a recrear nuestra especie en algun otra galaxia, en algun otro planeta, donde tenemos que comenzar desde cero absoluto y cometer los mismos errores del pasado? Me resisto a creer que eso sea posible, pero no esta muy lejana la posibilidad que eso este pasando en otro lugar en este mismo momento. ( Vease la ecuacion de Drake.)
Ojala y nuestros defectos e imperfecciones como seres vivientes, no se impongan ante nuestro deseo de seguir existiendo como tales en este rincon o en cualquier otro lado del universo, a mi punto de vista, seria una gran perdida.
Ustedes que opinan?
Saludos.
Pero comenzar de nuevo, por suerte esta vez no tenemos que comenzar con herramientas rudimentarias como lo hicieron nuestros ancestros hace 65 millones de anios, sino que somos capaces de explicar de forma cientifica nuestro entorno, eso deberia darnos una ventaja abismal, y ser capaces de moldear este nuevo planeta en un habitat para seres humanos tal y como lo tenemos en nuestro globo terraqueo, en teoria.
Nuestro planeta se encuentra a la distancia exacta para que diversos procesos quimicos se desarrollen hasta el punto de crear seres multicelulares complejos, esto gracias a la existencia de agua en forma liquida, la orbita y rotacion estable del planeta, atmosfera y un campo magnetico que la protege de las inclemencias del sol; todos estos elementos contribuyen al sostenimiento de la vida en nuestro planeta, existe la posibilidad que semejantes combinaciones de elementos existan en otro punto del universo? Yo creo que si, pero el punto es que nuestra existencia aca esta limitada por la disponibilidad de elementos sostenedores de vida, o no?
En el caso de los dinosaurios, estos poblaban la tierra hasta hace unos 65 millones de anios, luego que segun la teoria del gran meteorito, acabo con ellos. Ese fue un evento totalmente fuera del control de los seres vivientes de esa epoca y podria ser nuestro caso tambien, ya paso una vez, volvera a pasar, cuando, quien sabe, pero para entonces es posible que ya hayamos encontrado la forma de habitar y adecuar otro planeta para nuestras necesidades, talvez para ese entonces, los cambios en el sol haran que en algun momento la distancia desde Marte hacia este, sea la distancia adecuada para el sostenimiento de vida tal y como la conocemos, haciendo de la Tierra solo un recuerdo y un planeta muy parecido a Venus, inhabitable.
El punto aqui es la perpetuidad de la especie humana, estamos aqui para quedarnos? lo dudo, la existencia del ser humano es tan solo un segundo si lo medimos en parametros desde la formacion del universo, pero lograremos perpetuar nuestra especie? me cuesta trabajo comprender que el ser humano, a pesar de todos sus defectos, desaparezca, y con el, todo el cumulo de informacion, tecnologia, arte, ciencias, etc. que hemos logrado desarrollar a lo largo de nuestra existencia. O es que el universo se empenia en volver a recrear nuestra especie en algun otra galaxia, en algun otro planeta, donde tenemos que comenzar desde cero absoluto y cometer los mismos errores del pasado? Me resisto a creer que eso sea posible, pero no esta muy lejana la posibilidad que eso este pasando en otro lugar en este mismo momento. ( Vease la ecuacion de Drake.)
Ojala y nuestros defectos e imperfecciones como seres vivientes, no se impongan ante nuestro deseo de seguir existiendo como tales en este rincon o en cualquier otro lado del universo, a mi punto de vista, seria una gran perdida.
Ustedes que opinan?
Saludos.
Promedio de Carga
Alguna vez se han preguntado que significan los valores denominados Load Average (Promedio de Carga) que aparecen en los comandos uptime y top de Linux/Unix? Bueno yo me hice esa misma pregunta hace un buen rato y buscando respuestas encontre varias explicaciones, desde las estadisticas que explican los metodos utilizados para calcular dichos resultados, hasta las que usan analogias para comparar a los procesadores como los carriles de una autopista y a los vehiculos en ella como los procesos haciendo uso de los procesadores.
En resumen, se puede decir que el promedio de carga del CPU es la suma promedio del numero de procesos esperando en la cola de execucion, mas el numero de procesos executandose en el ultimo minuto, asi como los ultimos 5 y 15 minutos, respectivamente; es de recalcar que estos datos se obtienen exclusivamente de los procesos que demandan atencion del CPU.
Para poner un ejemplo, consideremos la siguiente salida del comando uptime (el mismo resultado se obtiene del comando top):
15:43 up 14 days, 4:52, 13 users, load averages: 2.43, 2.96, 3.41
De lo anterios podemos observar que la carga promedio sobre el(los) CPU(s) en el ultimo minuto es 2.43, en los ultimos 5 minutos es de 2.96 y en los ultimos 15 minutos ha sido de 3.41.
De lo anterior podemos extraer lo siguiente:
Finalmente podemos mencionar que en un sistema donde el promedio de carga es significativamente mayor que el numero de CPU's disponibles, entonces el sistema pasa considerablemente ocupado, o saturado con algun tipo de problema tipo cuello de botella. Por el contrario, un equipo donde el promedio de carga es menor que el numero de CPUs en el sistema, probablemente se encuentra funcionando bien.
Para mas informacion: http://www.linuxjournal.com/article/9001?page=0,1
Saludos y hasta la proxima.
En resumen, se puede decir que el promedio de carga del CPU es la suma promedio del numero de procesos esperando en la cola de execucion, mas el numero de procesos executandose en el ultimo minuto, asi como los ultimos 5 y 15 minutos, respectivamente; es de recalcar que estos datos se obtienen exclusivamente de los procesos que demandan atencion del CPU.
Para poner un ejemplo, consideremos la siguiente salida del comando uptime (el mismo resultado se obtiene del comando top):
15:43 up 14 days, 4:52, 13 users, load averages: 2.43, 2.96, 3.41
De lo anterios podemos observar que la carga promedio sobre el(los) CPU(s) en el ultimo minuto es 2.43, en los ultimos 5 minutos es de 2.96 y en los ultimos 15 minutos ha sido de 3.41.
De lo anterior podemos extraer lo siguiente:
- En promedio, en el minuto anterior ha habido 2.43 procesos ejecutandose o esperando por recursos.
- En general, la tendencia del sistema es hacia un uso menor de los recursos, dado que el numero de procesos ejecutandose y en espera de recursos en el ultimo minuto (2.43) es menor que el registrado en los ultimos 5 minutos(2.96), asi como en los ultimos 15 minutos, cuando el promedio era de 3.41 procesos ejecutandose o esperando recursos.
- Podemos decir que el sistema en su totalidad se encuentra ocupado, que tanto, es dificil saberlo solo con los valores de carga promedio, pero como mencionamos anteriormente, podemos ver su tendencia.
Finalmente podemos mencionar que en un sistema donde el promedio de carga es significativamente mayor que el numero de CPU's disponibles, entonces el sistema pasa considerablemente ocupado, o saturado con algun tipo de problema tipo cuello de botella. Por el contrario, un equipo donde el promedio de carga es menor que el numero de CPUs en el sistema, probablemente se encuentra funcionando bien.
Para mas informacion: http://www.linuxjournal.com/article/9001?page=0,1
Saludos y hasta la proxima.
Monday, March 29, 2010
Parece que las bases de datos relacionales tienen competencia fuerte.
Una nueva ola de almacenar datos esta revolucionando la insdustria en los ultimos meses, y definitivamente nombres reconocidos en la industria estan reconociendo sus bondades, pero de que estamos hablando? Al parecer el tradicional LAMP, una combinacion ganadora en los ultimos anios y que ha hecho uso extensivo de bases de datos relacionales como MySQL y PostgreSQL, parece cosa del pasado, y es que la nueva modalidad de bases de datos no relacionales o (Non-SQL como tambien les llaman en Ingles) son la nueva panacea en el almacenamiento de informacion (o mejor dicho documentos).
Pero que esta motivando este cambio:
Los nuevos protagonistas en el almacenamiento de bases de datos difieren en algunas funcionalidades, pero en general todos se basan en un conjunto de caracteristicas de alto nivel, entre las cuales podemos mencionar:
Hace unas semanas el grupo de usuarios de Python de Utah hizo una presentacion sobre esta base de datos y en ellas se demostro su funcionalidad en el desarrollo de una pequena aplicacion, tambien se hablo un poco de la historia de la base de datos y sus caracteristicas, las cuales pueden encontrarse en el sitio web oficial, pero basicamente CouchDB es una base de datos orientada a documentos.
A continuacion mostramos como instalar la aplicacion en Fedora 12, asi como la libreria de Python para acceder a la base de datos; luego un programa que accede a la base de datos y muestra como hacer ciertas operaciones con los datos de la misma.
[fdiaz@fedora12 ~]$ sudo yum install couchdb python-couchdb
[sudo] password for fdiaz:
Loaded plugins: presto, refresh-packagekit
adobe-linux-i386 | 951 B 00:00
rpmfusion-free-updates | 3.3 kB 00:00
rpmfusion-nonfree-updates | 3.3 kB 00:00
updates/metalink | 15 kB 00:00
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package couchdb.i686 0:0.10.0-2.fc12 set to be updated
--> Processing Dependency: libicu-devel for package: couchdb-0.10.0-2.fc12.i686
--> Processing Dependency: libjs.so.1 for package: couchdb-0.10.0-2.fc12.i686
--> Processing Dependency: erlang for package: couchdb-0.10.0-2.fc12.i686
---> Package python-couchdb.noarch 0:0.6.1-2.fc12 set to be updated
--> Running transaction check
---> Package erlang.i686 0:R13B-04.1.fc12 set to be updated
--> Processing Dependency: libodbc.so.2 for package: erlang-R13B-04.1.fc12.i686
---> Package js.i686 0:1.70-8.fc12 set to be updated
---> Package libicu-devel.i686 0:4.2.1-7.fc12 set to be updated
--> Running transaction check
---> Package unixODBC.i686 0:2.2.14-9.fc12 set to be updated
--> Finished Dependency Resolution
Dependencies Resolved
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
couchdb i686 0.10.0-2.fc12 fedora 513 k
python-couchdb noarch 0.6.1-2.fc12 updates 83 k
Installing for dependencies:
erlang i686 R13B-04.1.fc12 updates 33 M
js i686 1.70-8.fc12 fedora 346 k
libicu-devel i686 4.2.1-7.fc12 updates 616 k
unixODBC i686 2.2.14-9.fc12 updates 381 k
Transaction Summary
================================================================================
Install 6 Package(s)
Upgrade 0 Package(s)
Total download size: 35 M
Is this ok [y/N]: y
Downloading Packages:
Setting up and reading Presto delta metadata
updates/prestodelta | 689 kB 00:03
Processing delta metadata
Package(s) data still to download: 35 M
(1/6): couchdb-0.10.0-2.fc12.i686.rpm | 513 kB 00:02
(2/6): erlang-R13B-04.1.fc12.i686.rpm | 33 MB 03:16
(3/6): js-1.70-8.fc12.i686.rpm | 346 kB 00:02
(4/6): libicu-devel-4.2.1-7.fc12.i686.rpm | 616 kB 00:03
(5/6): python-couchdb-0.6.1-2.fc12.noarch.rpm | 83 kB 00:00
(6/6): unixODBC-2.2.14-9.fc12.i686.rpm | 381 kB 00:02
--------------------------------------------------------------------------------
Total 169 kB/s | 35 MB 03:30
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : unixODBC-2.2.14-9.fc12.i686 1/6
Installing : erlang-R13B-04.1.fc12.i686 2/6
Installing : js-1.70-8.fc12.i686 3/6
Installing : libicu-devel-4.2.1-7.fc12.i686 4/6
Installing : couchdb-0.10.0-2.fc12.i686 5/6
Installing : python-couchdb-0.6.1-2.fc12.noarch 6/6
Installed:
couchdb.i686 0:0.10.0-2.fc12 python-couchdb.noarch 0:0.6.1-2.fc12
Dependency Installed:
erlang.i686 0:R13B-04.1.fc12 js.i686 0:1.70-8.fc12
libicu-devel.i686 0:4.2.1-7.fc12 unixODBC.i686 0:2.2.14-9.fc12
Complete!
You have new mail in /var/spool/mail/fdiaz
[fdiaz@fedora12 ~]$
Una vez la aplicacion se ha instalado, podemos iniciar el servicio mediante el siguiente comando:
[fdiaz@fedora12 ~]$ sudo /etc/init.d/couchdb start
Starting couchdb: Apache CouchDB has started, time to relax.
[ OK ]
Para acceder a la base de datos, hacemos uso de un explorador y nos dirigimos a la siguiente direccion:
http://localhost:5984/_utils/index.html
El servicio responde con una aplicacion web en la cual podremos acceder a la base de datos y hacer algunas operaciones, les invito a que le den un vistazo; pero programaticamente, podemos hacer uso del lenguaje de programacion Python para hacer las mismas operaciones como veremos a continuacion en el siguiente programa:
================ couchDBTest.py ===============
#! /usr/bin/python
import httplib, simplejson # Librerias para efectuar las llamadas HTTP y para acceder
# a los elementos json devueltos por la base de datos.
def Imprimir(s):
"""Imprimir muestra el resultado json de un objeto HTTP Respond"""
# Respuesta HTTP -> Diccionario de Python -> cadena
print simplejson.dumps(simplejson.loads(s.read()), sort_keys=True, indent=4)
class Couch:
"""Utilizaremos una clase para encapsular las acciones de la base de datos"""
def __init__(self, servidor, puerto=5984, options=None):
self.servidor = servidor
self.puerto = puerto
def conectar(self):
return httplib.HTTPConnection(self.servidor, self.puerto) # Hacemos una coneccion
# al servicio de la base de datos mediante metodos HTTP
# Operaciones basicas en la base de datos
def creaDB(self, nombreBD):
"""crea una nueva base de datos en el servidor"""
r = self.put(''.join(['/',nombreBD,'/']), "")
Imprimir(r)
def borraDB(self, nombreBD):
"""Elimina la base de datos del servidor"""
r = self.delete(''.join(['/',nombreBD,'/']))
Imprimir(r)
def listaDB(self):
"""Muestra un listado de las bases de datos disponibles en el servidor"""
Imprimir(self.get('/_all_dbs'))
def infoDb(self, nombreBD):
"""Muestra informacion sobre la base de datos"""
r = self.get(''.join(['/', nombreBD, '/']))
Imprimir(r)
# Operaciones sobre los documentos en la base de datos
def listDoc(self, nombreBD):
"""Muestra una lista de todos los documentos en la base de datos"""
r = self.get(''.join(['/', nombreBD, '/', '_all_docs']))
Imprimir(r)
def abreDoc(self, nombreBD, docId):
"""Abre un documento en una base de datos en particular"""
r = self.get(''.join(['/', nombreBD, '/', docId,]))
Imprimir(r)
def guardaDoc(self, nombreBD, contenido, docId=None):
"""Guarda o crea un documento en la base de datos especificada"""
if docId:
r = self.put(''.join(['/', nombreBD, '/', docId]), contenido)
else:
r = self.post(''.join(['/', nombreBD, '/']), contenido)
Imprimir(r)
def borraDoc(self, nombreBD, docId):
"""Elimina un documento, especificado por su docID, de la base de datos
segun la documentacion de CouchDB, la llamada debe identificar el documento
por medio de la revision del mismo, asi que primero hacemos un get segun el docid,
luego de-serializamos el objeto json, lo cual nos devuelve un diccionario y de el
extraemos el item '_rev' que es el parametro que pasamos para finalmente borrar
el documento.
"""
t = self.get(''.join(['/', nombreBD, '/', docId,]))
obj = simplejson.loads(t.read())
r = self.delete(''.join(['/', nombreBD, '/',docId,'?rev=',obj['_rev']]))
Imprimir(r)
# metodos HTTP
def get(self, uri):
c = self.conectar()
encabezado = {"Accept": "application/json"}
c.request("GET", uri, None, encabezado)
return c.getresponse()
def post(self, uri, contenido):
c = self.conectar()
encabezado = {"Content-type": "application/json"}
c.request('POST', uri, contenido, encabezado)
return c.getresponse()
def put(self, uri, contenido):
c = self.conectar()
if len(contenido) > 0:
encabezado = {"Content-type": "application/json"}
c.request("PUT", uri, contenido, encabezado)
else:
c.request("PUT", uri, contenido)
return c.getresponse()
def delete(self, uri):
c = self.conectar()
c.request("DELETE", uri)
return c.getresponse()
def main():
foo = Couch('localhost', '5984')
print "\nCreamos la base de datos 'bddoc':"
foo.creaDB('bddoc')
print "\nLista de bases de datos en el servidor:"
foo.listaDB()
print "\nCreamos un documento en la base de datos 'bddoc' con id: 00001:"
doc = """
{
"valor":
{
"Titulo":"Programacion Python y CouchDB",
"Autor":"FcoDiaz",
"Fecha":"2010-03-29T11:30:12-06:00",
"Tags":["couchDB", "python", "REST", "json"],
"Contenido":"Practicando un rato con CouchDB y Python.",
"Idioma":"Espanol"
}
}
"""
foo.guardaDoc('bddoc', doc,'00001')
doc2 = """
{
"valor":
{
"Titulo":"Programacion en C++",
"Autor":"FcoDiaz",
"Fecha":"2010-03-29T11:30:12-06:00",
"Tags":["C++", "Programacion"],
"Contenido":"Practicando un rato con C++.",
"Editorial":"FcoDiaz Publicaciones"
}
}
"""
print "\nCrea un segundo documento, el id sera seleccionado por la BD"
foo.guardaDoc('bddoc', doc2)
print "\nMuestra todos los documentos en la base de datos 'bddoc'"
foo.listDoc('bddoc')
print "\nRecuperamos el documento con codigo 00001 de la base de datos 'bddoc':"
foo.abreDoc('bddoc', '00001')
raw_input("Presiona ENTER para continuar")
print "\nBorramos el documento con codigo '00001' de la base de datos 'bddoc':"
foo.borraDoc('bddoc', '00001')
print "\nNuevamente mostramos los documentos en la base de datos 'bddoc'"
foo.listDoc('bddoc')
raw_input("Presiona ENTER para continuar")
print "\nInformacion de la base de datos 'bddoc':"
foo.infoDb('bddoc')
print "\nBorra la base de datos 'bddoc':"
foo.borraDB('bddoc')
print "\nLista de bases de datos en el servidor:"
foo.listaDB()
if __name__ == "__main__":
main()
==========
Para ejecutar el programa, lo guardamos y posteriormente podemos usar la siguiente linea de comandos para correr el programa, el resultado del programa puede verse a continuacion; he agregado algunas pausas para que mientras el programa espera por la tecla Return para continuar, se pueda observar el estado de la base de datos mediante el navegador, como se explico anteriormente y donde se podran observar la nueva base de datos y los documentos creados.
[fdiaz@fedora12 Python]$ python couchDBTest.py
Creamos la base de datos 'bddoc':
{
"ok": true
}
Lista de bases de datos en el servidor:
[
"bddoc"
]
Creamos un documento en la base de datos 'bddoc' con id: 00001:
{
"id": "00001",
"ok": true,
"rev": "1-7ddb0ea5569142bae2ce8879d56adb97"
}
Crea un documento, el codigo sera seleccionado por la BD
{
"id": "d5907db4ebd8fb240a8be36e24d56c43",
"ok": true,
"rev": "1-75ca9f69056f030781dfefd128c664c9"
}
Muestra todos los documentos en la base de datos 'bddoc'
{
"offset": 0,
"rows": [
{
"id": "00001",
"key": "00001",
"value": {
"rev": "1-7ddb0ea5569142bae2ce8879d56adb97"
}
},
{
"id": "d5907db4ebd8fb240a8be36e24d56c43",
"key": "d5907db4ebd8fb240a8be36e24d56c43",
"value": {
"rev": "1-75ca9f69056f030781dfefd128c664c9"
}
}
],
"total_rows": 2
}
Recuperamos el documento con codigo 00001 de la base de datos 'bddoc':
{
"_id": "00001",
"_rev": "1-7ddb0ea5569142bae2ce8879d56adb97",
"valor": {
"Autor": "FcoDiaz",
"Contenido": "Practicando un rato con CouchDB y Python.",
"Fecha": "2010-03-29T11:30:12-06:00",
"Idioma": "Espanol",
"Tags": [
"couchDB",
"python",
"REST",
"json"
],
"Titulo": "Programacion Python y CouchDB"
}
}
Presiona ENTER para continuar
Borramos el documento con codigo '00001' de la base de datos 'bddoc':
{
"id": "00001",
"ok": true,
"rev": "2-cf6064d2287d8c685d90eecebf58dfb6"
}
Nuevamente mostramos los documentos en la base de datos 'bddoc'
{
"offset": 0,
"rows": [
{
"id": "d5907db4ebd8fb240a8be36e24d56c43",
"key": "d5907db4ebd8fb240a8be36e24d56c43",
"value": {
"rev": "1-75ca9f69056f030781dfefd128c664c9"
}
}
],
"total_rows": 1
}
Presiona ENTER para continuar
Informacion de la base de datos 'bddoc':
{
"compact_running": false,
"db_name": "bddoc",
"disk_format_version": 4,
"disk_size": 4589,
"doc_count": 1,
"doc_del_count": 1,
"instance_start_time": "1269893376165905",
"purge_seq": 0,
"update_seq": 3
}
Borra la base de datos 'bddoc':
{
"ok": true
}
Lista de bases de datos en el servidor:
[]
[fdiaz@fedora12 Python]$
Algunas cosas que se observan de al menos los dos elementos de datos presentados es que la estructura de datos utilizada es un diccionario de Python y que los elementos de cada uno de los datos pueden variar, como es el caso del Idioma y Editorial, lo cual da una gran flexibilidad a los datos en caso que estos cambien constantemente de forma y estructura. Las bases de datos no relacionales han existido desde hace ya buen rato, de hecho yo trabaje en una llamada Minisis, alla por los 90's, y la base de datos era execelente para almacenar el catalogo de libros de una biblioteca; como podran ver la orientacion de estas bases de datos es hacia los documentos, donde estos forman un elemento primordial en sistemas recientes que ademas abarcan una gran cantidad de usuarios como lo por ejemplo las redes sociales. Tambien puede ser utilizada en sistemas no tan complejos que requiran bases de datos sencillas y donde la recuperacion de datos esta mas enfocada en busquedas sobre la llave primaria.
Finalmente algunas companias que estan haciendo el cambio a este tipo de bases de datos tenemos:
Facebook y Twitter: Cassandra
Google: Big Table
LinkedIn: Voldemort
Mas informacion sobre CouchDB: http://couchdb.apache.org/
O sobre la libreria de Python para CouchDB: http://wiki.apache.org/couchdb/Getting_started_with_Python
Hasta la proxima.
Pero que esta motivando este cambio:
- En muchos casos las bases de datos relacionales no son la respuesta a todos los requerimientos de almacenamiento de datos.
- Las bases de datos relacionales presentan obstaculos para su uso en ambientes distribuidos.
- La normalizacion usualmente impacta en el desempeno de la base de datos.
- En muchas aplicaciones solamente es necesario hacer busquedas basadas en la llave primaria.
Los nuevos protagonistas en el almacenamiento de bases de datos difieren en algunas funcionalidades, pero en general todos se basan en un conjunto de caracteristicas de alto nivel, entre las cuales podemos mencionar:
- Son bases de datos no normalizadas, sin necesidad de esquemas y orientadas a documentos
- Bases de datos simples, basadas en el conjunto llave : valor; metodos de busqueda estan disponibles y se basan en busquedas de la llave primaria.
- Capacidad de uso distribuido, o crecimiento horizontal, donde replicas de la base de datos pueden ubicarse en diversos nodos de distribucion de contenidos para los usuarios.
- Replicacion es un punto importante como se menciono anteriormente, entonces esta debe ser una caracteristica importante de la base de datos.
- La base de datos se accede mediante llamadas usando el formato RESTful, o mediante API
- Soporte del metodo de programacion o framework Map Reduce introducido por Google para el analisis de datos.
- Consistencia.
Hace unas semanas el grupo de usuarios de Python de Utah hizo una presentacion sobre esta base de datos y en ellas se demostro su funcionalidad en el desarrollo de una pequena aplicacion, tambien se hablo un poco de la historia de la base de datos y sus caracteristicas, las cuales pueden encontrarse en el sitio web oficial, pero basicamente CouchDB es una base de datos orientada a documentos.
A continuacion mostramos como instalar la aplicacion en Fedora 12, asi como la libreria de Python para acceder a la base de datos; luego un programa que accede a la base de datos y muestra como hacer ciertas operaciones con los datos de la misma.
[fdiaz@fedora12 ~]$ sudo yum install couchdb python-couchdb
[sudo] password for fdiaz:
Loaded plugins: presto, refresh-packagekit
adobe-linux-i386 | 951 B 00:00
rpmfusion-free-updates | 3.3 kB 00:00
rpmfusion-nonfree-updates | 3.3 kB 00:00
updates/metalink | 15 kB 00:00
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package couchdb.i686 0:0.10.0-2.fc12 set to be updated
--> Processing Dependency: libicu-devel for package: couchdb-0.10.0-2.fc12.i686
--> Processing Dependency: libjs.so.1 for package: couchdb-0.10.0-2.fc12.i686
--> Processing Dependency: erlang for package: couchdb-0.10.0-2.fc12.i686
---> Package python-couchdb.noarch 0:0.6.1-2.fc12 set to be updated
--> Running transaction check
---> Package erlang.i686 0:R13B-04.1.fc12 set to be updated
--> Processing Dependency: libodbc.so.2 for package: erlang-R13B-04.1.fc12.i686
---> Package js.i686 0:1.70-8.fc12 set to be updated
---> Package libicu-devel.i686 0:4.2.1-7.fc12 set to be updated
--> Running transaction check
---> Package unixODBC.i686 0:2.2.14-9.fc12 set to be updated
--> Finished Dependency Resolution
Dependencies Resolved
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
couchdb i686 0.10.0-2.fc12 fedora 513 k
python-couchdb noarch 0.6.1-2.fc12 updates 83 k
Installing for dependencies:
erlang i686 R13B-04.1.fc12 updates 33 M
js i686 1.70-8.fc12 fedora 346 k
libicu-devel i686 4.2.1-7.fc12 updates 616 k
unixODBC i686 2.2.14-9.fc12 updates 381 k
Transaction Summary
================================================================================
Install 6 Package(s)
Upgrade 0 Package(s)
Total download size: 35 M
Is this ok [y/N]: y
Downloading Packages:
Setting up and reading Presto delta metadata
updates/prestodelta | 689 kB 00:03
Processing delta metadata
Package(s) data still to download: 35 M
(1/6): couchdb-0.10.0-2.fc12.i686.rpm | 513 kB 00:02
(2/6): erlang-R13B-04.1.fc12.i686.rpm | 33 MB 03:16
(3/6): js-1.70-8.fc12.i686.rpm | 346 kB 00:02
(4/6): libicu-devel-4.2.1-7.fc12.i686.rpm | 616 kB 00:03
(5/6): python-couchdb-0.6.1-2.fc12.noarch.rpm | 83 kB 00:00
(6/6): unixODBC-2.2.14-9.fc12.i686.rpm | 381 kB 00:02
--------------------------------------------------------------------------------
Total 169 kB/s | 35 MB 03:30
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : unixODBC-2.2.14-9.fc12.i686 1/6
Installing : erlang-R13B-04.1.fc12.i686 2/6
Installing : js-1.70-8.fc12.i686 3/6
Installing : libicu-devel-4.2.1-7.fc12.i686 4/6
Installing : couchdb-0.10.0-2.fc12.i686 5/6
Installing : python-couchdb-0.6.1-2.fc12.noarch 6/6
Installed:
couchdb.i686 0:0.10.0-2.fc12 python-couchdb.noarch 0:0.6.1-2.fc12
Dependency Installed:
erlang.i686 0:R13B-04.1.fc12 js.i686 0:1.70-8.fc12
libicu-devel.i686 0:4.2.1-7.fc12 unixODBC.i686 0:2.2.14-9.fc12
Complete!
You have new mail in /var/spool/mail/fdiaz
[fdiaz@fedora12 ~]$
Una vez la aplicacion se ha instalado, podemos iniciar el servicio mediante el siguiente comando:
[fdiaz@fedora12 ~]$ sudo /etc/init.d/couchdb start
Starting couchdb: Apache CouchDB has started, time to relax.
[ OK ]
Para acceder a la base de datos, hacemos uso de un explorador y nos dirigimos a la siguiente direccion:
http://localhost:5984/_utils/index.html
El servicio responde con una aplicacion web en la cual podremos acceder a la base de datos y hacer algunas operaciones, les invito a que le den un vistazo; pero programaticamente, podemos hacer uso del lenguaje de programacion Python para hacer las mismas operaciones como veremos a continuacion en el siguiente programa:
================ couchDBTest.py ===============
#! /usr/bin/python
import httplib, simplejson # Librerias para efectuar las llamadas HTTP y para acceder
# a los elementos json devueltos por la base de datos.
def Imprimir(s):
"""Imprimir muestra el resultado json de un objeto HTTP Respond"""
# Respuesta HTTP -> Diccionario de Python -> cadena
print simplejson.dumps(simplejson.loads(s.read()), sort_keys=True, indent=4)
class Couch:
"""Utilizaremos una clase para encapsular las acciones de la base de datos"""
def __init__(self, servidor, puerto=5984, options=None):
self.servidor = servidor
self.puerto = puerto
def conectar(self):
return httplib.HTTPConnection(self.servidor, self.puerto) # Hacemos una coneccion
# al servicio de la base de datos mediante metodos HTTP
# Operaciones basicas en la base de datos
def creaDB(self, nombreBD):
"""crea una nueva base de datos en el servidor"""
r = self.put(''.join(['/',nombreBD,'/']), "")
Imprimir(r)
def borraDB(self, nombreBD):
"""Elimina la base de datos del servidor"""
r = self.delete(''.join(['/',nombreBD,'/']))
Imprimir(r)
def listaDB(self):
"""Muestra un listado de las bases de datos disponibles en el servidor"""
Imprimir(self.get('/_all_dbs'))
def infoDb(self, nombreBD):
"""Muestra informacion sobre la base de datos"""
r = self.get(''.join(['/', nombreBD, '/']))
Imprimir(r)
# Operaciones sobre los documentos en la base de datos
def listDoc(self, nombreBD):
"""Muestra una lista de todos los documentos en la base de datos"""
r = self.get(''.join(['/', nombreBD, '/', '_all_docs']))
Imprimir(r)
def abreDoc(self, nombreBD, docId):
"""Abre un documento en una base de datos en particular"""
r = self.get(''.join(['/', nombreBD, '/', docId,]))
Imprimir(r)
def guardaDoc(self, nombreBD, contenido, docId=None):
"""Guarda o crea un documento en la base de datos especificada"""
if docId:
r = self.put(''.join(['/', nombreBD, '/', docId]), contenido)
else:
r = self.post(''.join(['/', nombreBD, '/']), contenido)
Imprimir(r)
def borraDoc(self, nombreBD, docId):
"""Elimina un documento, especificado por su docID, de la base de datos
segun la documentacion de CouchDB, la llamada debe identificar el documento
por medio de la revision del mismo, asi que primero hacemos un get segun el docid,
luego de-serializamos el objeto json, lo cual nos devuelve un diccionario y de el
extraemos el item '_rev' que es el parametro que pasamos para finalmente borrar
el documento.
"""
t = self.get(''.join(['/', nombreBD, '/', docId,]))
obj = simplejson.loads(t.read())
r = self.delete(''.join(['/', nombreBD, '/',docId,'?rev=',obj['_rev']]))
Imprimir(r)
# metodos HTTP
def get(self, uri):
c = self.conectar()
encabezado = {"Accept": "application/json"}
c.request("GET", uri, None, encabezado)
return c.getresponse()
def post(self, uri, contenido):
c = self.conectar()
encabezado = {"Content-type": "application/json"}
c.request('POST', uri, contenido, encabezado)
return c.getresponse()
def put(self, uri, contenido):
c = self.conectar()
if len(contenido) > 0:
encabezado = {"Content-type": "application/json"}
c.request("PUT", uri, contenido, encabezado)
else:
c.request("PUT", uri, contenido)
return c.getresponse()
def delete(self, uri):
c = self.conectar()
c.request("DELETE", uri)
return c.getresponse()
def main():
foo = Couch('localhost', '5984')
print "\nCreamos la base de datos 'bddoc':"
foo.creaDB('bddoc')
print "\nLista de bases de datos en el servidor:"
foo.listaDB()
print "\nCreamos un documento en la base de datos 'bddoc' con id: 00001:"
doc = """
{
"valor":
{
"Titulo":"Programacion Python y CouchDB",
"Autor":"FcoDiaz",
"Fecha":"2010-03-29T11:30:12-06:00",
"Tags":["couchDB", "python", "REST", "json"],
"Contenido":"Practicando un rato con CouchDB y Python.",
"Idioma":"Espanol"
}
}
"""
foo.guardaDoc('bddoc', doc,'00001')
doc2 = """
{
"valor":
{
"Titulo":"Programacion en C++",
"Autor":"FcoDiaz",
"Fecha":"2010-03-29T11:30:12-06:00",
"Tags":["C++", "Programacion"],
"Contenido":"Practicando un rato con C++.",
"Editorial":"FcoDiaz Publicaciones"
}
}
"""
print "\nCrea un segundo documento, el id sera seleccionado por la BD"
foo.guardaDoc('bddoc', doc2)
print "\nMuestra todos los documentos en la base de datos 'bddoc'"
foo.listDoc('bddoc')
print "\nRecuperamos el documento con codigo 00001 de la base de datos 'bddoc':"
foo.abreDoc('bddoc', '00001')
raw_input("Presiona ENTER para continuar")
print "\nBorramos el documento con codigo '00001' de la base de datos 'bddoc':"
foo.borraDoc('bddoc', '00001')
print "\nNuevamente mostramos los documentos en la base de datos 'bddoc'"
foo.listDoc('bddoc')
raw_input("Presiona ENTER para continuar")
print "\nInformacion de la base de datos 'bddoc':"
foo.infoDb('bddoc')
print "\nBorra la base de datos 'bddoc':"
foo.borraDB('bddoc')
print "\nLista de bases de datos en el servidor:"
foo.listaDB()
if __name__ == "__main__":
main()
==========
Para ejecutar el programa, lo guardamos y posteriormente podemos usar la siguiente linea de comandos para correr el programa, el resultado del programa puede verse a continuacion; he agregado algunas pausas para que mientras el programa espera por la tecla Return para continuar, se pueda observar el estado de la base de datos mediante el navegador, como se explico anteriormente y donde se podran observar la nueva base de datos y los documentos creados.
[fdiaz@fedora12 Python]$ python couchDBTest.py
Creamos la base de datos 'bddoc':
{
"ok": true
}
Lista de bases de datos en el servidor:
[
"bddoc"
]
Creamos un documento en la base de datos 'bddoc' con id: 00001:
{
"id": "00001",
"ok": true,
"rev": "1-7ddb0ea5569142bae2ce8879d56adb97"
}
Crea un documento, el codigo sera seleccionado por la BD
{
"id": "d5907db4ebd8fb240a8be36e24d56c43",
"ok": true,
"rev": "1-75ca9f69056f030781dfefd128c664c9"
}
Muestra todos los documentos en la base de datos 'bddoc'
{
"offset": 0,
"rows": [
{
"id": "00001",
"key": "00001",
"value": {
"rev": "1-7ddb0ea5569142bae2ce8879d56adb97"
}
},
{
"id": "d5907db4ebd8fb240a8be36e24d56c43",
"key": "d5907db4ebd8fb240a8be36e24d56c43",
"value": {
"rev": "1-75ca9f69056f030781dfefd128c664c9"
}
}
],
"total_rows": 2
}
Recuperamos el documento con codigo 00001 de la base de datos 'bddoc':
{
"_id": "00001",
"_rev": "1-7ddb0ea5569142bae2ce8879d56adb97",
"valor": {
"Autor": "FcoDiaz",
"Contenido": "Practicando un rato con CouchDB y Python.",
"Fecha": "2010-03-29T11:30:12-06:00",
"Idioma": "Espanol",
"Tags": [
"couchDB",
"python",
"REST",
"json"
],
"Titulo": "Programacion Python y CouchDB"
}
}
Presiona ENTER para continuar
Borramos el documento con codigo '00001' de la base de datos 'bddoc':
{
"id": "00001",
"ok": true,
"rev": "2-cf6064d2287d8c685d90eecebf58dfb6"
}
Nuevamente mostramos los documentos en la base de datos 'bddoc'
{
"offset": 0,
"rows": [
{
"id": "d5907db4ebd8fb240a8be36e24d56c43",
"key": "d5907db4ebd8fb240a8be36e24d56c43",
"value": {
"rev": "1-75ca9f69056f030781dfefd128c664c9"
}
}
],
"total_rows": 1
}
Presiona ENTER para continuar
Informacion de la base de datos 'bddoc':
{
"compact_running": false,
"db_name": "bddoc",
"disk_format_version": 4,
"disk_size": 4589,
"doc_count": 1,
"doc_del_count": 1,
"instance_start_time": "1269893376165905",
"purge_seq": 0,
"update_seq": 3
}
Borra la base de datos 'bddoc':
{
"ok": true
}
Lista de bases de datos en el servidor:
[]
[fdiaz@fedora12 Python]$
Algunas cosas que se observan de al menos los dos elementos de datos presentados es que la estructura de datos utilizada es un diccionario de Python y que los elementos de cada uno de los datos pueden variar, como es el caso del Idioma y Editorial, lo cual da una gran flexibilidad a los datos en caso que estos cambien constantemente de forma y estructura. Las bases de datos no relacionales han existido desde hace ya buen rato, de hecho yo trabaje en una llamada Minisis, alla por los 90's, y la base de datos era execelente para almacenar el catalogo de libros de una biblioteca; como podran ver la orientacion de estas bases de datos es hacia los documentos, donde estos forman un elemento primordial en sistemas recientes que ademas abarcan una gran cantidad de usuarios como lo por ejemplo las redes sociales. Tambien puede ser utilizada en sistemas no tan complejos que requiran bases de datos sencillas y donde la recuperacion de datos esta mas enfocada en busquedas sobre la llave primaria.
Finalmente algunas companias que estan haciendo el cambio a este tipo de bases de datos tenemos:
Facebook y Twitter: Cassandra
Google: Big Table
LinkedIn: Voldemort
Mas informacion sobre CouchDB: http://couchdb.apache.org/
O sobre la libreria de Python para CouchDB: http://wiki.apache.org/couchdb/Getting_started_with_Python
Hasta la proxima.
Subscribe to:
Posts (Atom)