miércoles, 28 de abril de 2010

0003 Excel - PostgreSQL


En muchas ocasiones me he encontrado con el siguiente problema: "¿Cómo hacer para pasar datos de Excel a postgreSQL?" Para ésta pregunta hay varias respuestas:
  1. La más común es pasar del formato XLS, (Excel), a el formato CSV, (comma-separated values), y desde postgreSQL llamar al archivo CSV por medio de un procedimiento almacenado para añadir los datos a una tabla en la base de datos.
  2. Otra forma es usar los drivers ODBC desde el archivo de Excel para pasar los datos de las celdas a una tabla o varia tablas en postgreSQL.
  3. Una tercera sería pasar los datos desde Excel a MS-Access
    y luego desde Access pasar a postgreSQL.
En el siguiente tutorial explico cómo leer directamente los datos desde un archivo de Excel mediante un procedimiento almacenado de postgreSQL para añadir los datos a una tabla.
Con los métodos antes expuestos tenemos los siguientes problemas:
  • Excel a CSV: Cada vez que se haga una modificación sobre el archivo de Excel habrá que pasar nuevamente al formato CSV para leer los nuevos valores.
  • Excel con ODBC: Si se tienen varios archivos de Excel, cada uno de ellos tiene que estar configurado para poder trabajar con el driver ODBC, si uno de ellos no está configurado entonces no se podrá pasar la información a la base de datos. Otro inconveniente es que se tiene que ejecutar el archivo de Excel cada vez que se hagan cambios en sus celdas.
  • Excel a Access: Los mismos problemas antes mencionados, añadiendo un nivel extra de incomodidad y dificultad al proceso cada vez que se hagan actualizaciones en los archivos de Excel.
Método a tratar: Leer el archivo desde un procedimiento almacenado de postgreSQL.
¿Qué ventaja puede traer este método?: Al estar el proceso de lectura de un archivo de Excel en un procedimiento almacenado en postgreSQL, se automatiza el proceso de actualización de datos de la tabla relacionada cada vez que el usuario quiera con tantos archivos de Excel que se esté trabajando, eliminando así los inconvenientes antes mencionados.
¿Cómo es esto posible?: Una de las razones por la cual he seleccionado postgreSQL como plataforma de base de datos es su capacidad para usar varios lenguajes de programación para el desarrollo de procedimientos almacenados y es aquí donde viene el "quid" de la cuestión. Para leer directamente de un archivo de Excel desde un procedimiento almacenado en postgreSQL se va a usar el lenguaje plpythonu, una vez leídas las celdas, los datos de éstas serán guardadas en la tabla correspondiente.
El siguiente ejemplo es muy sencillo pero será suficiente para ver el funcionamiento del procedimiento.
Aplicaciones y versiones que se usaron para este ejemplo:
AplicaciónVersión
S.O.: Windows 76.1 compilación 7600
PostgreSQL8.4
Python2.6.5
MS-Excel 200712.0.6524.5003 SP2


Librerias python que se usan para la comunicación con archivos de excel:
  • xlrd-0.7.1.win32 – web: xlrd
  • xlwt-0.7.2.win32 – web: xlwt
  • xlutils-1.4.1.win32 – web: xlutils 1.4.1
Una vez bajados, instalar los archivos empezando por el archivo xlrd-0.7.1.
Archivo Excel:

A
B
1
David
0
2
Jorge
1
3
Arturo
2
4
Sylvia
3
5
Carolina
4
6
Graciela
5
7
Fernando
6
8
Elena
7
9
Carlos
8
10
Daniela
9


Guardar el archivo en formato "Libro de Excel 97 – 2003 *.xls", en la ruta "c:\" con el nombre de prueba.xls, ejemplo: C:\prueba.xls

Crear tabla:
CREATE TABLE excel
(
campo1 character varying(20),
campo2 character varying(20)
)
WITH (
OIDS=FALSE
);
ALTER TABLE excel OWNER TO postgres;


Pocedimiento almacenado:
CREATE OR REPLACE FUNCTION fexcel1() RETURNS text AS
$BODY$
from xlrd import open_workbook,cellname
libro = open_workbook('c:/prueba.xls')
hoja = libro.sheet_by_index(0)
for row_index in range(hoja.nrows):
val1 = hoja.cell(row_index,0).value
val2 = hoja.cell(row_index,1).value
plpy.execute("INSERT INTO excel(campo1, campo2) VALUES ( '" + val1 + "', '" + str(val2) + "' )")
return "Funciona"
$BODY$
LANGUAGE 'plpythonu' VOLATILE
COST 100;
ALTER FUNCTION fexcel1() OWNER TO postgres;


Comentarios:
from xlrd import open_workbook,cellname:Esta línea indica que se va a importar la librería xlrd para abrir y leer un archivo de Excel.
libro = open_workbook('c:/prueba.xls'):Se abre el archivo de Excel y se asigna a la variable "libro".
hoja = libro.sheet_by_index(0):Se accede a la primera hoja del libro abierto y se le asigna a la variable "hoja".
for row_index in range(hoja.nrows):Se comienza un bucle con el número de iteraciones igual al número máximo de filas.
val1 = hoja.cell(row_index,0).value:Se asigna el valor de la fila en que se encuentre el bucle de la primera columna a la variable "val1".
val2 = hoja.cell(row_index,1).value:Se asigna el valor de la fila en que se encuentre el bucle de la segunda columna a la variable "val2".
plpy.execute("INSERT INTO excel(campo1, campo2) VALUES ( '" + val1 + "', '" + str(val2) + "' )"):Se ejecuta el "insert" para guardar los valores obtenidos de las celdas.


Ejecución del script:
select fexcel1();


Comentarios finales:
Con las librerías de python antes expuestas se pueden hacer muchas más cosas, como por ejemplo actualizar los valores de una celda en el archivo de Excel y combinando esto con postgreSQL se puede hacer la actualización de un libro obteniendo primero los datos de una tabla, aunque eso quedará para otro tutorial.
Recuerden instalar el lenguaje plpythonu, si no, este ejemplo no funcionará.
Sólo ha sido probado bajo Windows, los usuarios de Linux están marginados de momento.
Nota importante: Recién estoy aprendiendo python, cualquier comentario sobre el lenguaje les recomiendo que busquen por "San" google, les proporcionará más información de la que yo les puedo dar.
Muchas gracias.
Firma: XDRTAS


2 comentarios:

Anónimo dijo...

Excelente Post, de verdad muy bueno, se nota el profesionalismo con que expones.
Sldos.

Rusel Cierto Trinidad

xdrtas dijo...

Muchas gracias por tu comentario Rusel. Intento siempre exponer lo mejor posible las ideas para que sean fáciles de seguir.