lunes, 26 de octubre de 2015

Bases de datos y python

Trabajando con base de datos en python



Autor: Bruno Binner Quiñones
Competencia: Desarrollo de Software (Nivel 2)
Asignatura: Programación II
Palabras Clave: Base de datos, Python, sql, sqlite3, archivos


Descripción de la Actividad


La finalidad de la actividad era demostrar que tan útil, eficiente, y practico puede ser el uso de programas en python para desglosar archivos y llenar datos en una base de datos.
El ejercicio consistía en llenar, con el uso de python, la tabla ‘ventas’, de una base de datos llamada ‘datos.db’, tabla la cual poseía la siguiente estructura:
{id: ipka, p: real, q: integer, v: real, f: ’dd-mm-yyyy’, t: varchar(1)}


Siendo:
p : Precio.
q : Cantidad vendida.
v : Venta, que es igual a la cantidad vendida multiplicada por el precio.
f : Fecha de la venta.
t : Es el tipo de pago. Dentro de los tipo de pago esta efectivo(e), visa(v), master(m) y cheque(c).


Los datos para llenar esta tabla están contenidos en un archivo de texto llamado ‘movi.txt’. Que contiene lo siguiente:



El archivo tiene un total de 100000 líneas.


Solución

Antes de empezar con el código hay que analizar la tabla y el archivo que contiene los datos para saber a que campo corresponde cada dato. Para esto hay que fijarse en el tipo de dato que soporta cada campo.
Como se puede apreciar en la siguiente imagen.
Lo encerrado en el cuadrilátero azul representa el tipo de dato de cada campo. Siendo 'integer' para guardar valores/números enteros, 'real' para números reales, y finalmente el 'varchar' que se usa para almacenar cualquier carácter (letras, números, símbolos, etc). Por ejemplo en el campo 'id' se podrían almacenar números tales como 10; 0; 331 o cualquier otro que no contenga números decimales. En 'p' se podrían poner números como 1.23; 0.2443;1323.2344 etc. Y en 'f' se podrían guardar cosas como palabras, números u otras cosas, cabe destacar que los números ingresados en un campo 'varchar' serán tomados como una cadena (string).
Bueno, ya analizados los datos sabemos que 'id' y 'q' contendrán números enteros, 'p' y 'v' almacenaran valores reales, y 'f' con 't' guardaran strings de texto.

Ahora iremos al archivo movi.txt para ver que datos corresponde a cada campo. Para esto nos centraremos en una de linea al azar del archivo que sera la siguiente.

Usando los '&' como referencia separaremos los datos de la siguiente forma.
En la imagen anterior se puede ver la linea separada por tipos de dato y también a que campos correspondería cada dato. Si se preguntan el por que el campo 'id' no esta en la imagen, es porque 'id' es un campo con autoincrement. Que quiere decir esto, significa que cada vez que se ingrese una linea en la tabla, los valores que tome 'id' serán generados automáticamente, haciendo que por cada linea el numero aumente en 1.

Ya con esto identificado pasamos al código.

Codigo sin comentarios:
  1. import sqlite3 as sq3

  2. con = sq3.connect('.\Base Datos\datos.db')
  3. cur = con.cursor()
  4. insert='insert into ventas(p,q,v,f,t) values(?,?,?,?,?);'

  5. f=open('movi.txt')
  6. d=f.readlines()

  7. for e in d:
  8. t=e[:-1].split('&')
  9. con.execute(insert ,((float(t[0]),int(t[1]),float(t[2]),t[3],t[4]))

  10. con.commit()


Codigo con comentarios:

import sqlite3 as sq3  
#Se importa el modulo de sqlite3 para poder trabajar con bases de datos.

con = sq3.connect('.\Base Datos\datos.db')  
#Se establece conexion con la base de datos hubicada en este caso en una carpeta llamada 
#'Base Datos' que esta en el mismo directorio donde se #encuentra el programa python.

cur = con.cursor() #Se crea un objeto cursor para poder hacer consultas sql a la base de datos.
insert='insert into ventas(p,q,v,f,t) values(?,?,?,?,?);'
# Se guarda en una variable, un string que contiene una orden para sql.

f=open('movi.txt') # Se abre el archivo movi.txt
d=f.readlines() # Se guarda en un arreglo las lineas del archivo

for e in d:
t=e[:-1].split('&')
con.execute(insert ,(float(t[0]),int(t[1]),float(t[2]),t[3],t[4]))
# Para cada linea se aplicara un split que separara los datos por cada & que encuentre, y se #guardaran en un arreglo, para luego ser insertados en la base de datos mediante el metodo #execute()

con.commit() # Se confirman los cambios realizados durante el codigo

En la linea 1 se importa el modulo sqlite3 para trabajar con la base de datos. Luego en la linea 3 se establece conexión con la base de datos, usando con = sq3.connect('.\Base Datos\datos.db'), ubicada en esta caso en una carpeta llamada 'Base Datos' que esta en el mismo directorio que el programa de python que estamos usando.
En la linea 4 con cur = con.cursor() se crea un objeto cursor para poder hacer consultas sql a la base de datos.
Se crea en la linea 5 una variable que contendrá un strin que sera el siguiente 'insert into ventas(p,q,v,f,t) values(?,?,?,?,?);' que explicaremos su propósito un poco mas adelante.
Luego abrimos el archivo movi.txt con f=open('movi.txt') y guardamos en un arreglo todas las lineas que este contiene, haciendo uso de f.readlines(). Por ejemplo lo que debería contener el primer elemento del arreglo es un string que seria el siguiente: 403.704218057&78&33733.1335705&08-5-2003&E\n
Si se fijan bien el salto de linea '\n' va incluido al final de cada cadena.

Luego en el siguiente segmento de código:
for e in d:
t=e[:-1].split('&')
con.execute(insert ,(float(t[0]),int(t[1]),float(t[2]),t[3],t[4]))

Se recorre el arreglo que contiene las lineas de movi.txt y en cada linea se aplica un t=e[:-1].split('&') que guardara en el arreglo t algo como esto:[403.704218057,78,33733.1335705,08-5-2003,E]
.split('&') Sirve para separar un string por cada & que encuentre y es para sacar el '\n' al final de cada linea.
Después con execute() insertamos los datos obtenidos en t en la tabla 'ventas'. La forma que funciona execute(orden_sql,valores) es que donde dice orden_sql se pone la orden o consulta que se hara a la base de datos en lenguaje sql, en nuestro caso 'insert into ventas(p,q,v,f,t) values(?,?,?,?,?);' y en valores se colocan los valores que reemplazaran los '?' que hay en orden_sql. O sea que lo que enrealidad esta escrito en execute() es
con.execute('insert into ventas(p,q,v,f,t) values(?,?,?,?,?);',(float(t[0]),int(t[1]),float(t[2]),t[3],t[4]))

Finalmente se confirman los cambios realizados en la tabla con con.commit() y se llena la tabla de los datos que habían en movi.txt. Quedando algo como en la siguiente imagen:

En qué me ayudó esta actividad

Una tarea que puede parecer extremadamente tediosa como lo seria llenar una tabla de una base de datos con 100000 lineas se puede realizar de forma sencilla con tan solo 10 lineas de un programa en python. Demostrando lo útil que es ocupar diferentes recursos para dar soluciones a diversas problemáticas, así como usar archivos de texto, desglosar la información que contienen y utilizarla.
Con este trabajo también aprendí lo versátil que puede ser el uso de archivos a momento de crear soluciones.


No hay comentarios:

Publicar un comentario