8 abr. 2012

Sqlalchemy y Elixir: Abstracción de Bases de Datos en Python

En el artículo anterior se explica como usar Sqlalchemy para acceder y manipular una base de datos abstrayendo el motor de la base de datos a utilizar.

Existe una herramienta que facilita aun más el trabajo de crear tablas, insertar, consultar o remover datos de dichas tablas; Elixir crea una capa declarativa sobre slqalchemy que permite usar la declaración de clases directamente a las tablas de entidad relación.

Igual que en el ejemplo anterior se usará las tablas Grupos y Contactos, la diferencia será que no será necesario definir un campo id para cada tabla, además la forma de declarar cual campo es primary key o foreign key es con la declaración de uno a muchos o de muchos a uno.

Este ejemplo crea las tablas, se realiza una inserción de datos a ambas tablas, se realiza unas consultas de datos y al final se elimina y dato de la tabla Contactos y se muestra que ya se elimino de dicha tabla.

El código python se muestra a continuación:
#!/usr/bin/env python

from elixir import metadata, Entity, Field
from elixir import Unicode, UnicodeText
from elixir import *

#Se asocia el metadato con la base de datos sqlite
metadata.bind = "sqlite:///prueba.db"
#Se activa el echo de los resultados de los comandos.
metadata.bind.echo = False

#Se crea la clase Grupos que hereda Entity, 
#se crea los campos grupo (unicode 150),
#descripcion (unicode 200) y
#contactos que es una referencia uno a muchos de la 
#clase Contactos.
class Grupos(Entity):
    grupo = Field(Unicode(150))
    descripcion = Field(Unicode(200))
    contactos = OneToMany('Contactos')
    
    #Devuelve la informacion de los grupos
    def __repr__(self):
        return '<Grupos "%s" (%s)>' % (self.grupo,self.descripcion)
        
#Se crea la clase contactos que hereda de Entity.
#se tiene el campo nombre (unicode 100),
#telefono (string 11) y el campo grupo muchos a uno de grupos.
class Contactos(Entity):
    nombre = Field(Unicode(100))
    telefono = Field(String(11))
    grupo = ManyToOne('Grupos')
    
    #Devuelve la informacion de los contactos
    def __repr__(self):
        return '<Contactos- nombre: "%s", telefono: "%s", grupo: "%s">' % (self.nombre,self.telefono,self.grupo)
        

if __name__ == "__main__":
    #Se importa create_all, setup_all y session de elixir.
    from elixir import create_all, setup_all, session
    #Se crea las clases segun los modelos.
    setup_all()
    #Se crea las tablas en la base de datos segun los modelos definidos
    create_all()
    
    #Se insertan datos en la tabla grupos
    #En este caso se agregan ciudades del pais.
    Guacara = Grupos(grupo='Guacara',descripcion='Ciudad del Estado Carabobo')
    Valencia = Grupos(grupo="Valencia",descripcion="Capital del Estado Carabobo")
    Barquisimeto = Grupos(grupo="Barquisimeto",descripcion="Capital del Estado Lara")
    Caracas = Grupos(grupo="Caracas",descripcion="Distrito Capital")
    Maracaibo = Grupos(grupo="Maracaibo",descripcion="Capital del Estado Zulia")
    Merida = Grupos(grupo="Merida",descripcion="Capital del Estado Merida")
    Barcelona = Grupos(grupo="Barcelona",descripcion="Capital de Anzoategui")
    PuertoOrdaz = Grupos(grupo="Puerto Ordaz",descripcion="Ciudad del Estado Bolivar")
    Barinas = Grupos(grupo="Barinas",descripcion="Capital del Estado Barinas")
    Maracay = Grupos(grupo="Maracay",descripcion="Capital del Estado Aragua")
    LosTeques = Grupos(grupo="Los Teques",descripcion="Capital del Estado Miranda")
    
    #Se hace el commit para insertar los datos de la tabla grupos en la base de datos.
    session.commit()
    
    #Se insertan datos en la tabla contactos, cada contacto hace referencia a un grupo de 
    #la tabla grupos.
    Contactos(nombre='Ernesto Nadir Crespo Avila',telefono='04205873118',grupo=Guacara)
    Contactos(nombre='Jhon Doe',telefono='04295333131',grupo=Valencia)
    Contactos(nombre='Jane Doe',telefono='04399991919',grupo=Caracas)
    Contactos(nombre='Pedro Perez',telefono='04596661617',grupo=Caracas)
    Contactos(nombre='Maria Perez',telefono='04194445445',grupo=Barquisimeto)
    #Se hace el commit para insertar los datos en la tabla contactos en la base de datos.
    session.commit()
    
    #Se realiza una consulta buscando los contactos del grupo Caracas
    #Y se presentan en pantalla
    registros = Contactos.query.filter(Contactos.grupo == Caracas).all()
    print "Contactos de Caracas"
    for registro in registros:
        print "-" * 20
        print registro.nombre
        print registro.telefono
        print registro.grupo
    print "*-" *20
        
    #Se muestra en pantalla todos los contactos.
    registros = Contactos.query.all()
    print "Todos los Contactos"
    for registro in registros:
        print "-" * 20
        print registro.nombre
        print registro.telefono
        print registro.grupo
    print "*-" *20
    #Se muestra en pantalla todos los grupos, con sus contactos
    #asociados.
    registros = Grupos.query.all()
    for registro in registros:
        print "-" * 20
        print registro.grupo
        print registro.descripcion
        print registro.contactos
    print "*-" *20
    #Se consulta la tabla contactos buscando al usuario Maria Perez
    #Se muestra en pantalla la informacion de ese contacto
    consulta = Contactos.query.filter_by(nombre=u'Maria Perez')
    registro = consulta.first()
    print "%s , %s :(%s)" % (registro.nombre,registro.telefono, registro.grupo)
    # Se borra ese contacto de la tabla contactos y se actualiza la base de datos.
    registro.delete()
    session.commit()
    
    #Se muestra en pantalla todos los contactos
    #para hacer notar que ya el contacto Maria Perez no existe
    #en la base de datos.
    registros = Contactos.query.all()
    print "Contactos, luego de eliminar a Maria Perez"
    for registro in registros:
        print "-" * 20
        print registro.nombre
        print registro.telefono
        print registro.grupo        

El código SQL generado a partir del modelo es el siguiente:
CREATE TABLE __main___grupos (         id INTEGER NOT NULL,         grupo VARCHAR(150),         descripcion VARCHAR(200),         PRIMARY KEY (id) )
CREATE TABLE __main___contactos (         id INTEGER NOT NULL,         nombre VARCHAR(100),         telefono VARCHAR(11),         grupo_id INTEGER,         PRIMARY KEY (id),         CONSTRAINT __main___contactos_grupo_id_fk FOREIGN KEY(grupo_id) REFERENCES __main___grupos (id) )
Con respecto al modelo el código SQL si tiene los campos id como PRIMARY KEY en cada tabla y se define cuales son FOREIGN KEY, gracias a Elixir se ahorra trabajo en la definición de campos y al usar OneToMany o ManyToOne se está definiendo quienes son primary o foreign key.

El resultado del script se muestra a continuación:
Contactos de Caracas
--------------------
Jane Doe
04399991919
<Grupos "Caracas" (Distrito Capital)>
--------------------
Pedro Perez
04596661617
<Grupos "Caracas" (Distrito Capital)>
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
Todos los Contactos
--------------------
Ernesto Nadir Crespo Avila
04205873118
<Grupos "Guacara" (Ciudad del Estado Carabobo)>
--------------------
Jhon Doe
04295333131
<Grupos "Valencia" (Capital del Estado Carabobo)>
--------------------
Jane Doe
04399991919
<Grupos "Caracas" (Distrito Capital)>
--------------------
Pedro Perez
04596661617
<Grupos "Caracas" (Distrito Capital)>
--------------------
Maria Perez
04194445445
<Grupos "Barquisimeto" (Capital del Estado Lara)>
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
--------------------
Guacara
Ciudad del Estado Carabobo
[<Contactos- nombre: "Ernesto Nadir Crespo Avila", telefono: "04205873118", grupo: "<Grupos "Guacara" (Ciudad del Estado Carabobo)>">]
--------------------
Valencia
Capital del Estado Carabobo
[<Contactos- nombre: "Jhon Doe", telefono: "04295333131", grupo: "<Grupos "Valencia" (Capital del Estado Carabobo)>">]
--------------------
Barquisimeto
Capital del Estado Lara
[<Contactos- nombre: "Maria Perez", telefono: "04194445445", grupo: "<Grupos "Barquisimeto" (Capital del Estado Lara)>">]
--------------------
Caracas
Distrito Capital
[<Contactos- nombre: "Jane Doe", telefono: "04399991919", grupo: "<Grupos "Caracas" (Distrito Capital)>">, <Contactos- nombre: "Pedro Perez", telefono: "04596661617", grupo: "<Grupos "Caracas" (Distrito Capital)>">]
--------------------
Maracaibo
Capital del Estado Zulia
[]
--------------------
Merida
Capital del Estado Merida
[]
--------------------
Barcelona
Capital de Anzoategui
[]
--------------------
Puerto Ordaz
Ciudad del Estado Bolivar
[]
--------------------
Barinas
Capital del Estado Barinas
[]
--------------------
Maracay
Capital del Estado Aragua
[]
--------------------
Los Teques
Capital del Estado Miranda
[]
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
Maria Perez , 04194445445 :(<Grupos "Barquisimeto" (Capital del Estado Lara)>)
Contactos, luego de eliminar a Maria Perez
--------------------
Ernesto Nadir Crespo Avila
04205873118
<Grupos "Guacara" (Ciudad del Estado Carabobo)>
--------------------
Jhon Doe
04295333131
<Grupos "Valencia" (Capital del Estado Carabobo)>
--------------------
Jane Doe
04399991919
<Grupos "Caracas" (Distrito Capital)>
--------------------
Pedro Perez
04596661617
<Grupos "Caracas" (Distrito Capital)>

Las herramientas sqlalchemy y Elixir facilitan el trabajo de abstraer el motor de base de datos y la creación de las tablas con sus respectivos campos en dichas base de datos.  De está forma se puede crear aplicaciones donde se puede facilitar el uso de varios motores de base de datos realizando cambios mínimos en la aplicación.

7 abr. 2012

Abstracción del motor de Base de Datos con el ORM Sqlalchemy y python

ORM o Mapeo de Objeto Relacional es una técnica de programación para convertir datos entre el sistema de tipos utilizando lenguajes de programación orientado a objetos y el utilizado en una Base de Datos Relacional (tomado de la wikipedia).

Sqlalchemy es una herramienta ORM para python que da flexibilidad en el desarrollo con SQL.

Tomando el artículo anterior de sqlite con python, se cambiará el módulo de sqlite3 para python por el ORM Sqlalchemy, de esa forma se abstrae las distintas instrucciones existentes para diferents motores de base de datos como postgresql, mysql, sqlite y se puede así utilizar cualquier motor de base de datos realizando mínimos cambios en el programa.

A continuación el código donde se muestra el uso de sqlalchemy en una base de datos sqlite3:
#!/usr/bin/env python #Se importa sqlalchemy from sqlalchemy import * #Se crea la instancia del motor de la base de datos y se asocia con un #archivo db = create_engine('sqlite:///tutorial.db') #se coloca la base de datos en modo no mostrar resultados #de las instrucciones en pantalla. db.echo = False #Se asocia el archivo de la base de datos a la instancia de metadatos. metadata = MetaData(db) #Se crea la tabla contactos tal cual el mismo ejemplo de #sqlite. contactos = Table(     'contactos',metadata,     Column('id',Integer,primary_key=True),     Column('nombre', Unicode(100)),     Column('telefono',String(11)),     Column('grupo_id', ForeignKey('grupos.id'))) #Se crea la tabla de grupos tal cual el mismo ejemplo de #sqlite grupos = Table(     'grupos',metadata,     Column('id',Integer,primary_key=True),     Column('grupo',Unicode(300)),     Column('descripcion',Unicode(500))) #Se crea todas las tablas. metadata.create_all() #Se inserta datos en la tabla grupos. i = grupos.insert() i.execute(grupo='Guacara',descripcion='Ciudad de Carabobo') i.execute({'grupo':'Valencia','descripcion':'Capital de Carabobo'},     {'grupo':'Maracay','descripcion':'Capital de Aragua'},     {'grupo':'Merida','descripcion':'Capital de Merida'}) #Se inserta datos en la tabla contactos    u = contactos.insert() u.execute(nombre='Ernesto Crespo',telefono='04155673029',grupo_id=1) u.execute(nombre='Pedro Perez',telefono='0295212223',grupo_id=2) u.execute(nombre='Jhon Doe',telefono='04184488484',grupo_id=2) u.execute(nombre='Jane Doe',telefono='04184488482',grupo_id=1) u.execute(nombre='Pepito de los palotes',telefono='04184588484',grupo_id=3) #Se hace consulta de la tabla contactos s = contactos.select() rs = s.execute() #Se hace consultas de la tabla grupos. t = grupos.select() ts = t.execute() #Se muestra la tabla grupos print "GRUPOS" print "-------------------------------------" for fila in ts:     print "id: %s,Grupo: %s, Descripcion:%s" %(fila[0],fila[1],fila[2]) print "--------------------------------------" del fila #Se muestra la tabla contactos. print "CONTACTOS" print "-------------------------------------" for fila in rs:     print "Nombre: %s, telefono %s, Grupo %s" %(fila[1],fila[2],fila[3]) print "--------------------------------------" #Se borra la fila del id 1 de la tabla grupos t = grupos.delete(text("id=1")) t.execute() #Se realiza una consulta de la tabla grupos q = grupos.select() qs = q.execute() #Se muestra la tabla grupos, #ahora no tiene la fila del grupo Guacara. print "GRUPOS" print "-------------------------------------" for fila in qs:     print "id: %s,Grupo: %s, Descripcion:%s" %(fila[0],fila[1],fila[2]) print "--------------------------------------" #Se muestra los contactos del grupo 2. print "Mostrar contactos del grupo 2" del q del qs q = contactos.select(text("grupo_id=2")) qs = q.execute() print "-------------------------------------" for fila in qs:     print "Nombre: %s, telefono %s, Grupo %s" %(fila[1],fila[2],fila[3]) print "--------------------------------------"
El resultado de ejecutar el script se muestra a continuación:

GRUPOS
-------------------------------------
id: 1,Grupo: Guacara, Descripcion:Ciudad de Carabobo
id: 2,Grupo: Valencia, Descripcion:Capital de Carabobo
id: 3,Grupo: Maracay, Descripcion:Capital de Aragua
id: 4,Grupo: Merida, Descripcion:Capital de Merida
--------------------------------------
CONTACTOS
-------------------------------------
Nombre: Ernesto Crespo, telefono 04155673029, Grupo 1
Nombre: Pedro Perez, telefono 0295212223, Grupo 2
Nombre: Jhon Doe, telefono 04184488484, Grupo 2
Nombre: Jane Doe, telefono 04184488482, Grupo 1
Nombre: Pepito de los palotes, telefono 04184588484, Grupo 3
--------------------------------------
GRUPOS
-------------------------------------
id: 2,Grupo: Valencia, Descripcion:Capital de Carabobo
id: 3,Grupo: Maracay, Descripcion:Capital de Aragua
id: 4,Grupo: Merida, Descripcion:Capital de Merida
--------------------------------------
Mostrar contactos del grupo 2
-------------------------------------
Nombre: Pedro Perez, telefono 0295212223, Grupo 2
Nombre: Jhon Doe, telefono 04184488484, Grupo 2
--------------------------------------

De está manera se facilita el trabajo de acceder a una base de datos sin estar usando directamente su API y facilita también poder utilizar cualquier motor de base de datos en la aplicación que se esté desarrollando.

6 abr. 2012

Simulación de circuitos eléctricos con python eispice

Eispice es un simulador de circuitos clone del Motor de simulación de Berkley Spice 3.

Lo interesante es que se puede usar el lenguaje de programación Python para realizar simulación de circuitos.

Tiene documentación de distintos ejemplos y un manual.

Para instalarlo se descarga la fuente del eispice. Se descomprime y luego se compila e instala:
tar -xvjf eispice-0.11.6.tar.bz2
cd eispice-0.11.6/
sudo python setup.py install


Un ejemplo sencillo muestra un circuito RC con una fuente sinusoidal, se muestra la gráfica de la tensión y la corriente.

La fuente estará entre el nodo de tierra y el nodo 1, la resistencia entre el nodo 1 y el nodo 2, el condensador estará entr el nodo 2 y el nodo tierra.

A continuación se muestra el código python de la definición del circuito:

#!/usr/bin/env python

#Importar modulo eispice
import eispice


#Se crea el circuito con el titulo
cct = eispice.Circuit("Prueba de circuito RC")

#Se crea la fuente de tension, con valor, se define un
#valor DC de 10, y una segnal senosoidal de valor offset, amplitud,
#frecuencia, retardo, amortiguacion.
cct.Vx = eispice.V(1, eispice.GND,10,eispice.Sin(10,10,'10M'))

#Resistencia de 20 K ohm.
cct.R1 = eispice.R(1,2,'20kOhm')

#Capacitor de 10 nano faradio.
cct.C1 = eispice.C(2,eispice.GND, '10n')

#Se ejecuta el analisis definiendo el tiempo de analisis.
cct.tran('0.5n', '100n')

#Se captura los resultados
resultados = cct.results
print "Se muestra los resultados"
print resultados

#Se crea la grafica
eispice.plot(cct)

El resultado de la ejecución y luego las gráficas:
Se muestra los resultados
[[  0.00000000e+00   1.00000000e+01  -1.35525272e-20   1.00000000e+01]
 [  5.00000000e-12   1.00031416e+01  -1.57079626e-07   1.00000000e+01]
 [  5.50000000e-12   1.00034558e+01  -1.72787588e-07   1.00000000e+01]
 [  6.50000000e-12   1.00040841e+01  -2.04203512e-07   1.00000000e+01]
 [  8.50000000e-12   1.00053407e+01  -2.67035355e-07   1.00000000e+01]
 [  1.25000000e-11   1.00078540e+01  -3.92699027e-07   1.00000000e+01]
 [  2.05000000e-11   1.00128805e+01  -6.44026281e-07   1.00000000e+01]
 [  3.65000000e-11   1.00229336e+01  -1.14668021e-06   1.00000000e+01]
 [  6.85000000e-11   1.00430397e+01  -2.15198395e-06   1.00000000e+01]
 [  1.32500000e-10   1.00832512e+01  -4.16256080e-06   1.00000000e+01]
 [  2.60500000e-10   1.01636697e+01  -8.18347813e-06   1.00000001e+01]
 [  5.16500000e-10   1.03244696e+01  -1.62234571e-05   1.00000004e+01]
 [  1.01650000e-09   1.06382517e+01  -3.19125016e-05   1.00000016e+01]
 [  1.51650000e-09   1.09514039e+01  -4.75700131e-05   1.00000036e+01]
 [  2.01650000e-09   1.12636172e+01  -6.31805394e-05   1.00000064e+01]
 [  2.51650000e-09   1.15745834e+01  -7.87286750e-05   1.00000099e+01]
 [  3.01650000e-09   1.18839958e+01  -9.41990756e-05   1.00000142e+01]
 [  3.51650000e-09   1.21915488e+01  -1.09576474e-04   1.00000193e+01]
 [  4.01650000e-09   1.24969391e+01  -1.24845694e-04   1.00000252e+01]
 [  4.51650000e-09   1.27998652e+01  -1.39991667e-04   1.00000318e+01]
 [  5.01650000e-09   1.31000281e+01  -1.54999446e-04   1.00000392e+01]
 [  5.51650000e-09   1.33971317e+01  -1.69854221e-04   1.00000473e+01]
 [  6.01650000e-09   1.36908828e+01  -1.84541330e-04   1.00000562e+01]
 [  6.51650000e-09   1.39809914e+01  -1.99046280e-04   1.00000658e+01]
 [  7.01650000e-09   1.42671712e+01  -2.13354756e-04   1.00000761e+01]
 [  7.51650000e-09   1.45491398e+01  -2.27452637e-04   1.00000871e+01]
 [  8.01650000e-09   1.48266190e+01  -2.41326011e-04   1.00000988e+01]
 [  8.51650000e-09   1.50993350e+01  -2.54961186e-04   1.00001112e+01]
 [  9.01650000e-09   1.53670184e+01  -2.68344706e-04   1.00001243e+01]
 [  9.51650000e-09   1.56294053e+01  -2.81463363e-04   1.00001381e+01]
 [  1.00165000e-08   1.58862366e+01  -2.94304210e-04   1.00001524e+01]
 [  1.05165000e-08   1.61372590e+01  -3.06854575e-04   1.00001675e+01]
 [  1.10165000e-08   1.63822246e+01  -3.19102073e-04   1.00001831e+01]
 [  1.15165000e-08   1.66208917e+01  -3.31034616e-04   1.00001994e+01]
 [  1.20165000e-08   1.68530248e+01  -3.42640428e-04   1.00002162e+01]
 [  1.25165000e-08   1.70783948e+01  -3.53908057e-04   1.00002336e+01]
 [  1.30165000e-08   1.72967792e+01  -3.64826381e-04   1.00002516e+01]
 [  1.35165000e-08   1.75079627e+01  -3.75384627e-04   1.00002701e+01]
 [  1.40165000e-08   1.77117366e+01  -3.85572374e-04   1.00002891e+01]
 [  1.45165000e-08   1.79079000e+01  -3.95379569e-04   1.00003087e+01]
 [  1.50165000e-08   1.80962593e+01  -4.04796533e-04   1.00003287e+01]
 [  1.55165000e-08   1.82766286e+01  -4.13813972e-04   1.00003491e+01]
 [  1.60165000e-08   1.84488298e+01  -4.22422987e-04   1.00003700e+01]
 [  1.65165000e-08   1.86126930e+01  -4.30615082e-04   1.00003914e+01]
 [  1.70165000e-08   1.87680566e+01  -4.38382173e-04   1.00004131e+01]
 [  1.75165000e-08   1.89147671e+01  -4.45716595e-04   1.00004352e+01]
 [  1.80165000e-08   1.90526798e+01  -4.52611109e-04   1.00004576e+01]
 [  1.85165000e-08   1.91816587e+01  -4.59058911e-04   1.00004804e+01]
 [  1.90165000e-08   1.93015763e+01  -4.65053638e-04   1.00005035e+01]
 [  1.95165000e-08   1.94123144e+01  -4.70589374e-04   1.00005269e+01]
 [  2.00165000e-08   1.95137637e+01  -4.75660656e-04   1.00005506e+01]
 [  2.05165000e-08   1.96058241e+01  -4.80262479e-04   1.00005745e+01]
 [  2.10165000e-08   1.96884046e+01  -4.84390302e-04   1.00005986e+01]
 [  2.15165000e-08   1.97614239e+01  -4.88040050e-04   1.00006229e+01]
 [  2.20165000e-08   1.98248099e+01  -4.91208123e-04   1.00006474e+01]
 [  2.25165000e-08   1.98784999e+01  -4.93891394e-04   1.00006720e+01]
 [  2.30165000e-08   1.99224410e+01  -4.96087214e-04   1.00006968e+01]
 [  2.35165000e-08   1.99565899e+01  -4.97793416e-04   1.00007216e+01]
 [  2.40165000e-08   1.99809129e+01  -4.99008317e-04   1.00007465e+01]
 [  2.45165000e-08   1.99953859e+01  -4.99730718e-04   1.00007715e+01]
 [  2.50165000e-08   1.99999946e+01  -4.99959906e-04   1.00007965e+01]
 [  2.55165000e-08   1.99947346e+01  -4.99695655e-04   1.00008215e+01]
 [  2.55665000e-08   1.99936659e+01  -4.99642097e-04   1.00008240e+01]
 [  2.56665000e-08   1.99912327e+01  -4.99520185e-04   1.00008290e+01]
 [  2.58665000e-08   1.99851830e+01  -4.99217203e-04   1.00008390e+01]
 [  2.62665000e-08   1.99683546e+01  -4.98374783e-04   1.00008589e+01]
 [  2.67665000e-08   1.99384666e+01  -4.96879139e-04   1.00008838e+01]
 [  2.72665000e-08   1.98987705e+01  -4.94893095e-04   1.00009086e+01]
 [  2.77665000e-08   1.98493055e+01  -4.92418613e-04   1.00009333e+01]
 [  2.82665000e-08   1.97901205e+01  -4.89458134e-04   1.00009578e+01]
 [  2.87665000e-08   1.97212738e+01  -4.86014579e-04   1.00009822e+01]
 [  2.92665000e-08   1.96428334e+01  -4.82091348e-04   1.00010064e+01]
 [  2.97665000e-08   1.95548766e+01  -4.77692311e-04   1.00010304e+01]
 [  3.02665000e-08   1.94574904e+01  -4.72821810e-04   1.00010542e+01]
 [  3.07665000e-08   1.93507707e+01  -4.67484652e-04   1.00010777e+01]
 [  3.12665000e-08   1.92348230e+01  -4.61686104e-04   1.00011009e+01]
 [  3.17665000e-08   1.91097616e+01  -4.55431888e-04   1.00011238e+01]
 [  3.22665000e-08   1.89757100e+01  -4.48728177e-04   1.00011464e+01]
 [  3.27665000e-08   1.88328004e+01  -4.41581585e-04   1.00011687e+01]
 [  3.32665000e-08   1.86811739e+01  -4.33999167e-04   1.00011906e+01]
 [  3.37665000e-08   1.85209802e+01  -4.25988405e-04   1.00012121e+01]
 [  3.42665000e-08   1.83523773e+01  -4.17557205e-04   1.00012332e+01]
 [  3.47665000e-08   1.81755316e+01  -4.08713886e-04   1.00012538e+01]
 [  3.52665000e-08   1.79906176e+01  -3.99467177e-04   1.00012740e+01]
 [  3.57665000e-08   1.77978178e+01  -3.89826203e-04   1.00012938e+01]
 [  3.62665000e-08   1.75973226e+01  -3.79800478e-04   1.00013130e+01]
 [  3.67665000e-08   1.73893297e+01  -3.69399897e-04   1.00013317e+01]
 [  3.72665000e-08   1.71740444e+01  -3.58634724e-04   1.00013499e+01]
 [  3.77665000e-08   1.69516792e+01  -3.47515582e-04   1.00013676e+01]
 [  3.82665000e-08   1.67224536e+01  -3.36053445e-04   1.00013847e+01]
 [  3.87665000e-08   1.64865937e+01  -3.24259624e-04   1.00014012e+01]
 [  3.92665000e-08   1.62443323e+01  -3.12145759e-04   1.00014171e+01]
 [  3.97665000e-08   1.59959085e+01  -2.99723805e-04   1.00014324e+01]
 [  4.02665000e-08   1.57415675e+01  -2.87006020e-04   1.00014471e+01]
 [  4.07665000e-08   1.54815602e+01  -2.74004956e-04   1.00014611e+01]
 [  4.12665000e-08   1.52161433e+01  -2.60733442e-04   1.00014745e+01]
 [  4.17665000e-08   1.49455787e+01  -2.47204577e-04   1.00014872e+01]
 [  4.22665000e-08   1.46701334e+01  -2.33431712e-04   1.00014992e+01]
 [  4.27665000e-08   1.43900793e+01  -2.19428438e-04   1.00015105e+01]
 [  4.32665000e-08   1.41056926e+01  -2.05208576e-04   1.00015211e+01]
 [  4.37665000e-08   1.38172542e+01  -1.90786158e-04   1.00015310e+01]
 [  4.42665000e-08   1.35250486e+01  -1.76175418e-04   1.00015402e+01]
 [  4.47665000e-08   1.32293641e+01  -1.61390776e-04   1.00015486e+01]
 [  4.52665000e-08   1.29304927e+01  -1.46446820e-04   1.00015563e+01]
 [  4.57665000e-08   1.26287293e+01  -1.31358300e-04   1.00015633e+01]
 [  4.62665000e-08   1.23243716e+01  -1.16140106e-04   1.00015695e+01]
 [  4.67665000e-08   1.20177200e+01  -1.00807257e-04   1.00015749e+01]
 [  4.72665000e-08   1.17090772e+01  -8.53748836e-05   1.00015795e+01]
 [  4.77665000e-08   1.13987477e+01  -6.98582163e-05   1.00015834e+01]
 [  4.82665000e-08   1.10870379e+01  -5.42725681e-05   1.00015865e+01]
 [  4.87665000e-08   1.07742552e+01  -3.86333202e-05   1.00015888e+01]
 [  4.92665000e-08   1.04607085e+01  -2.29559067e-05   1.00015904e+01]
 [  4.97665000e-08   1.01467071e+01  -7.25579914e-06   1.00015911e+01]
 [  5.02665000e-08   9.83256094e+00   8.45150824e-06   1.00015911e+01]
 [  5.07665000e-08   9.51858000e+00   2.41505143e-05   1.00015903e+01]
 [  5.12665000e-08   9.20507417e+00   3.98257259e-05   1.00015887e+01]
 [  5.17665000e-08   8.89235283e+00   5.54616736e-05   1.00015863e+01]
 [  5.22665000e-08   8.58072461e+00   7.10429265e-05   1.00015831e+01]
 [  5.27665000e-08   8.27049704e+00   8.65541080e-05   1.00015792e+01]
 [  5.32665000e-08   7.96197628e+00   1.01979910e-04   1.00015745e+01]
 [  5.37665000e-08   7.65546681e+00   1.17305110e-04   1.00015690e+01]
 [  5.42665000e-08   7.35127111e+00   1.32514583e-04   1.00015628e+01]
 [  5.47665000e-08   7.04968938e+00   1.47593319e-04   1.00015558e+01]
 [  5.52665000e-08   6.75101925e+00   1.62526438e-04   1.00015480e+01]
 [  5.57665000e-08   6.45555548e+00   1.77299202e-04   1.00015395e+01]
 [  5.62665000e-08   6.16358964e+00   1.91897032e-04   1.00015303e+01]
 [  5.67665000e-08   5.87540988e+00   2.06305522e-04   1.00015203e+01]
 [  5.72665000e-08   5.59130059e+00   2.20510453e-04   1.00015097e+01]
 [  5.77665000e-08   5.31154215e+00   2.34497806e-04   1.00014983e+01]
 [  5.82665000e-08   5.03641065e+00   2.48253778e-04   1.00014862e+01]
 [  5.87665000e-08   4.76617762e+00   2.61764792e-04   1.00014735e+01]
 [  5.92665000e-08   4.50110974e+00   2.75017515e-04   1.00014600e+01]
 [  5.97665000e-08   4.24146860e+00   2.87998868e-04   1.00014460e+01]
 [  6.02665000e-08   3.98751044e+00   3.00696040e-04   1.00014312e+01]
 [  6.07665000e-08   3.73948588e+00   3.13096501e-04   1.00014159e+01]
 [  6.12665000e-08   3.49763969e+00   3.25188013e-04   1.00013999e+01]
 [  6.17665000e-08   3.26221054e+00   3.36958643e-04   1.00013834e+01]
 [  6.22665000e-08   3.03343078e+00   3.48396774e-04   1.00013663e+01]
 [  6.27665000e-08   2.81152618e+00   3.59491119e-04   1.00013486e+01]
 [  6.32665000e-08   2.59671573e+00   3.70230729e-04   1.00013303e+01]
 [  6.37665000e-08   2.38921144e+00   3.80605005e-04   1.00013115e+01]
 [  6.42665000e-08   2.18921807e+00   3.90603710e-04   1.00012923e+01]
 [  6.47665000e-08   1.99693300e+00   4.00216975e-04   1.00012725e+01]
 [  6.52665000e-08   1.81254600e+00   4.09435313e-04   1.00012523e+01]
 [  6.57665000e-08   1.63623902e+00   4.18249627e-04   1.00012316e+01]
 [  6.62665000e-08   1.46818606e+00   4.26651219e-04   1.00012104e+01]
 [  6.67665000e-08   1.30855298e+00   4.34631797e-04   1.00011889e+01]
 [  6.72665000e-08   1.15749730e+00   4.42183484e-04   1.00011670e+01]
 [  6.77665000e-08   1.01516811e+00   4.49298830e-04   1.00011447e+01]
 [  6.82665000e-08   8.81705858e-01   4.55970811e-04   1.00011221e+01]
 [  6.87665000e-08   7.57242264e-01   4.62192843e-04   1.00010991e+01]
 [  6.92665000e-08   6.41900155e-01   4.67958785e-04   1.00010759e+01]
 [  6.97665000e-08   5.35793362e-01   4.73262948e-04   1.00010523e+01]
 [  7.02665000e-08   4.39026598e-01   4.78100097e-04   1.00010285e+01]
 [  7.07665000e-08   3.51695360e-01   4.82465459e-04   1.00010045e+01]
 [  7.12665000e-08   2.73885834e-01   4.86354724e-04   1.00009803e+01]
 [  7.17665000e-08   2.05674809e-01   4.89764055e-04   1.00009559e+01]
 [  7.22665000e-08   1.47129600e-01   4.92690087e-04   1.00009313e+01]
 [  7.27665000e-08   9.83079844e-02   4.95129933e-04   1.00009067e+01]
 [  7.32665000e-08   5.92581435e-02   4.97081185e-04   1.00008818e+01]
 [  7.37665000e-08   3.00186147e-02   4.98541917e-04   1.00008570e+01]
 [  7.42665000e-08   1.06182539e-02   4.99510688e-04   1.00008320e+01]
 [  7.47665000e-08   1.07620677e-03   4.99986541e-04   1.00008070e+01]
 [  7.52665000e-08   1.40189027e-03   4.99969006e-04   1.00007820e+01]
 [  7.53165000e-08   1.97725580e-03   4.99940113e-04   1.00007795e+01]
 [  7.54165000e-08   3.42400955e-03   4.99867526e-04   1.00007745e+01]
 [  7.56165000e-08   7.50138747e-03   4.99663157e-04   1.00007645e+01]
 [  7.60165000e-08   2.03890444e-02   4.99017775e-04   1.00007446e+01]
 [  7.65165000e-08   4.53613489e-02   4.97767914e-04   1.00007196e+01]
 [  7.70165000e-08   8.01576799e-02   4.96026855e-04   1.00006948e+01]
 [  7.75165000e-08   1.24743698e-01   4.93796317e-04   1.00006700e+01]
 [  7.80165000e-08   1.79075401e-01   4.91078501e-04   1.00006454e+01]
 [  7.85165000e-08   2.43099172e-01   4.87876089e-04   1.00006209e+01]
 [  7.90165000e-08   3.16751825e-01   4.84192241e-04   1.00005966e+01]
 [  7.95165000e-08   3.99960675e-01   4.80030593e-04   1.00005725e+01]
 [  8.00165000e-08   4.92643606e-01   4.75395252e-04   1.00005487e+01]
 [  8.05165000e-08   5.94709149e-01   4.70290793e-04   1.00005250e+01]
 [  8.10165000e-08   7.06056578e-01   4.64722253e-04   1.00005016e+01]
 [  8.15165000e-08   8.26576008e-01   4.58695127e-04   1.00004785e+01]
 [  8.20165000e-08   9.56148500e-01   4.52215364e-04   1.00004558e+01]
 [  8.25165000e-08   1.09464618e+00   4.45289358e-04   1.00004333e+01]
 [  8.30165000e-08   1.24193237e+00   4.37923944e-04   1.00004113e+01]
 [  8.35165000e-08   1.39786172e+00   4.30126392e-04   1.00003896e+01]
 [  8.40165000e-08   1.56228033e+00   4.21904396e-04   1.00003683e+01]
 [  8.45165000e-08   1.73502596e+00   4.13266071e-04   1.00003474e+01]
 [  8.50165000e-08   1.91592812e+00   4.04219941e-04   1.00003269e+01]
 [  8.55165000e-08   2.10480829e+00   3.94774934e-04   1.00003070e+01]
 [  8.60165000e-08   2.30148005e+00   3.84940371e-04   1.00002875e+01]
 [  8.65165000e-08   2.50574932e+00   3.74725958e-04   1.00002685e+01]
 [  8.70165000e-08   2.71741452e+00   3.64141775e-04   1.00002500e+01]
 [  8.75165000e-08   2.93626674e+00   3.53198267e-04   1.00002321e+01]
 [  8.80165000e-08   3.16209002e+00   3.41906234e-04   1.00002147e+01]
 [  8.85165000e-08   3.39466149e+00   3.30276820e-04   1.00001979e+01]
 [  8.90165000e-08   3.63375163e+00   3.18321502e-04   1.00001817e+01]
 [  8.95165000e-08   3.87912449e+00   3.06052079e-04   1.00001661e+01]
 [  9.00165000e-08   4.13053792e+00   2.93480658e-04   1.00001511e+01]
 [  9.05165000e-08   4.38774380e+00   2.80619647e-04   1.00001367e+01]
 [  9.10165000e-08   4.65048829e+00   2.67481737e-04   1.00001230e+01]
 [  9.15165000e-08   4.91851211e+00   2.54079894e-04   1.00001100e+01]
 [  9.20165000e-08   5.19155074e+00   2.40427344e-04   1.00000976e+01]
 [  9.25165000e-08   5.46933473e+00   2.26537561e-04   1.00000859e+01]
 [  9.30165000e-08   5.75158994e+00   2.12424252e-04   1.00000750e+01]
 [  9.35165000e-08   6.03803782e+00   1.98101344e-04   1.00000647e+01]
 [  9.40165000e-08   6.32839568e+00   1.83582975e-04   1.00000552e+01]
 [  9.45165000e-08   6.62237697e+00   1.68883470e-04   1.00000464e+01]
 [  9.50165000e-08   6.91969156e+00   1.54017336e-04   1.00000383e+01]
 [  9.55165000e-08   7.22004605e+00   1.38999246e-04   1.00000310e+01]
 [  9.60165000e-08   7.52314401e+00   1.23844019e-04   1.00000244e+01]
 [  9.65165000e-08   7.82868634e+00   1.08566612e-04   1.00000186e+01]
 [  9.70165000e-08   8.13637148e+00   9.31821027e-05   1.00000135e+01]
 [  9.75165000e-08   8.44589581e+00   7.77056729e-05   1.00000093e+01]
 [  9.80165000e-08   8.75695384e+00   6.21525962e-05   1.00000058e+01]
 [  9.85165000e-08   9.06923862e+00   4.65382217e-05   1.00000031e+01]
 [  9.90165000e-08   9.38244194e+00   3.08779588e-05   1.00000011e+01]
 [  9.95165000e-08   9.69625472e+00   1.51872623e-05   9.99999996e+00]
 [  1.00000000e-07   1.00000000e+01  -2.02048261e-11   9.99999960e+00]]


4 abr. 2012

Sqlite con python

El programa pysms-send tendrá algunas mejoras, entre ellas manejara libreta de contactos.

Para ello se probará con sqlite3 o con mongoDB. Para esté artículo se trabajará con sqlite3. Se creará 2 tablas, una de contactos y otra de grupos. La de contactos tiene los campos de id, nombre del contacto, telefono y grupo. La tabla grupo tendrá los campos id, nombre del grupo y descripción del grupo.

En la tabla contactos el campo grupo es una referencia al id de la tabla grupo de esa forma cada contacto está relacionado a un grupo.


El archivo contactos.sql contiene lo siguiente:
create table contactos (
id integer primary key,
nombre text not null,
grupo integer references grupos(id)
on delete restrict
deferrable initially deferred,
telefono text not null default 'Desconocido',
unique (nombre,telefono));

create table grupos (
id integer primary key,
nombre text not null,             
descripcion text not null CHECK(descripcion !=''),
unique (nombre));

En la tabla contactos se tiene el campo id que es entero y clave primaria, luego el campo nombre es no nulo, el campo grupo hace referencia a la tabla grupos al campo id, el campo telefono es un texto no nulo con valor por defecto Desconocido, los valores únicos son el nombre y el teléfono, con eso se evita que existan números de teléfonos repetidos.

En la tabla grupos tiene el campo id es un entero y es clave primaria, el campo nombre es texto no nulo, el campo descripción es no nulo y se verifica que no sea un string vácio, el campo único es el nombre.

Para generar la base de datos se ejecuta la siguiente instrucción:
sqlite3 sms.db < sms.sql

De está manera se crea la base de datos sqlite en el archivo sms.db.

Si se desea interactuar con la base de datos se ejecuta sqlite3 con el nombre de la base de datos, se abrirá un interprete:

ecrespo@jewel:~/bin/python$ sqlite3 sms.db
SQLite version 3.7.11 2012-03-20 11:35:50
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite>

A continuación se agrega un grupo a la tabla grupos:
sqlite> insert into grupos (nombre,descripcion) values ('Guacara','Ciudad del Estado Carabobo');

Ahora se agrega un contacto a la tabla contactos:
insert into contactos (nombre,grupo,telefono) values ('Ernesto Crespo',1,'04315633119');


Se consulta a la tabla grupos y luego a la tabla contactos:
sqlite> select * from grupos;
1|Guacara|Ciudad del Estado Carabobo
sqlite> select * from contactos ;
1|Ernesto Crespo|1|04315633119


Para eliminar el contacto de se ejecuta:
sqlite> delete from contactos where id=1;

Se uso el id para eliminar el contacto.


A continuación  se crearán una serie de scripts en python que permitirán insertar datos a la base de datos, consultar datos y eliminarlos (las acciones básicas en una base de datos).

#!/usr/bin/env python
# -*- coding: utf-8 -*-

#Se importa el modulo sqlite3
import sqlite3

#Se crea la funcion main
def main():
    #Se establece la instancia connect a la base de datos sms.db
    con = sqlite3.connect("sms.db")
    #Se crea el cursor que permite la ejecucion de instrucciones sql
    cur = con.cursor()
   
    #Se crea una lista con tuplas como sus elementos.
    #Las tuplas contienen los datos a insertar en la tabla grupos.
    datos =[('valencia' ,'Capital Estado Carabobo'),
            ('Maracay','Capital Estado Aragua'),
            ('Barquisimeto','Capital del Estado Lara'),]
    #Se recorre la lista
    for t in datos:
        cur.execute('insert into grupos (nombre,descripcion) values (?,?)',t)
    #Se realiza la transaccion.
    con.commit()
   
    #Ahora se lista los datos de la tabla grupos
    cur.execute('select * from grupos')
    #Se captura uno
    fila = cur.fetchone()
    #Se recorre cada fila
    while fila:
        #Se muestra los elementos nombre y descripcion.
        print fila[1],fila[2]
        #Se pasa a la siguiente fila
        fila = cur.fetchone()
   
    #Se cierra el cursor
    cur.close()
    #Se cierra la conexion.
    con.close()
   
    #Se sale de la funcion .
    return 0
   
if __name__ == '__main__':
    main()


Al ejecutar el script devuelve la lista de grupos con su descripción:

ecrespo@jewel:~/bin/python$ python grupos-sms.py
Guacara Ciudad del Estado Carabobo
valencia Capital Estado Carabobo
Maracay Capital Estado Aragua
Barquisimeto Capital del Estado Lara

AddThis