Conectar Python con SQL

Vamos a usar la librería sqlite3, que está instalada por defecto en Python.

In [17]:
import sqlite3

Ahora vamos a crear un conector.

In [18]:
conn = sqlite3.connect(':memory:')

Aquí trabajamos con una base de datos "temporal", cargada en memoria.

Si queremos trabajar en una base de datos concreta hacemos lo siguiente:

In [12]:
conn = sqlite3.connect('empleados.db')

(Si no está creada ya nos la crea)

In [19]:
c = conn.cursor()

Un string entre tres comillas

""" Hola
esto es un 
string """

Es lo que se llama un docstring y es un string que se puede escribir en varias líneas

In [20]:
docstring= """ Esto
es un 
docstring.


Hola qué tal.


----Hola-----"""
In [21]:
print(docstring)
 Esto
es un 
docstring.


Hola qué tal.


----Hola-----

Vamos a crear una tabla:

In [22]:
c.execute("""CREATE TABLE empleados(
nombre text,
apellido text,
sueldo integer
)
""")
Out[22]:
<sqlite3.Cursor at 0x7fbd8c1792d0>

En SQLite los tipos son distintos que en MySQL. https://www.sqlite.org/datatype3.html

In [23]:
conn.commit()

Cerramos el conector:

In [24]:
conn.close()
In [25]:
conn = sqlite3.connect(':memory:')
c= conn.cursor()

c.execute("""CREATE TABLE empleados(
nombre text,
apellido text,
sueldo integer
)
""")

conn.commit()

conn.close()

Ahora vamos a añadir un empleado:

In [27]:
conn = sqlite3.connect(':memory:')
c= conn.cursor()

c.execute("""CREATE TABLE empleados(
nombre text,
apellido text,
sueldo integer
)
""")

c.execute("INSERT INTO empleados VALUES ('Juan','López',50000)")

conn.commit()

conn.close()

Vamos a hacer una consulta:

In [28]:
conn = sqlite3.connect(':memory:')
c= conn.cursor()

c.execute("""CREATE TABLE empleados(
nombre text,
apellido text,
sueldo integer
)
""")

c.execute("INSERT INTO empleados VALUES ('Juan','López',50000)")
conn.commit()

c.execute("SELECT * FROM empleados")

conn.close()

Para sacar el valor de la consulta usamos fetchone

In [29]:
conn = sqlite3.connect(':memory:')
c= conn.cursor()

c.execute("""CREATE TABLE empleados(
nombre text,
apellido text,
sueldo integer
)
""")

c.execute("INSERT INTO empleados VALUES ('Juan','López',50000)")
conn.commit()

c.execute("SELECT * FROM empleados")

print(c.fetchone())

conn.close()
('Juan', 'López', 50000)
In [32]:
conn = sqlite3.connect(':memory:')
c= conn.cursor()

c.execute("""CREATE TABLE empleados(
nombre text,
apellido text,
sueldo integer
)
""")

c.execute("INSERT INTO empleados VALUES ('Juan','López',50000)")
#conn.commit()

c.execute("SELECT * FROM empleados")

print(c.fetchone())

conn.close()
('Juan', 'López', 50000)
In [35]:
conn = sqlite3.connect('empleados3.db')
c= conn.cursor()

c.execute("""CREATE TABLE empleados(
nombre text,
apellido text,
sueldo integer
)
""")

c.execute("INSERT INTO empleados VALUES ('Juan','López',50000)")
conn.commit()

c.execute("SELECT * FROM empleados")

print(c.fetchone())

conn.close()
('Juan', 'López', 50000)
In [37]:
conn = sqlite3.connect(':memory:')
c= conn.cursor()

c.execute("""CREATE TABLE empleados(
nombre text,
apellido text,
sueldo integer
)
""")

c.execute("""INSERT INTO empleados VALUES 
            ('Juan','López',50000),
            ('María', 'López', 40000),
            ('Pedro','Pérez', 30000),
            ('Eduardo','Campuzano', 10),
            ('Guillermo','Gallego',1000000000),
            ('Fulanito', 'de Tal', 100000000000)""")

conn.commit()

c.execute("SELECT * FROM empleados")

print(c.fetchone()) # fetchone me saca uno solo

conn.close()
('Juan', 'López', 50000)

Si quiero sacar varios uso fetchmany

In [38]:
conn = sqlite3.connect(':memory:')
c= conn.cursor()

c.execute("""CREATE TABLE empleados(
nombre text,
apellido text,
sueldo integer
)
""")

c.execute("""INSERT INTO empleados VALUES 
            ('Juan','López',50000),
            ('María', 'López', 40000),
            ('Pedro','Pérez', 30000),
            ('Eduardo','Campuzano', 10),
            ('Guillermo','Gallego',1000000000),
            ('Fulanito', 'de Tal', 100000000000)""")

conn.commit()

c.execute("SELECT * FROM empleados")

print(c.fetchmany(5))

conn.close()
[('Juan', 'López', 50000), ('María', 'López', 40000), ('Pedro', 'Pérez', 30000), ('Eduardo', 'Campuzano', 10), ('Guillermo', 'Gallego', 1000000000)]

Si quiero sacar todos, uso fetchall

In [39]:
conn = sqlite3.connect(':memory:')
c= conn.cursor()

c.execute("""CREATE TABLE empleados(
nombre text,
apellido text,
sueldo integer
)
""")

c.execute("""INSERT INTO empleados VALUES 
            ('Juan','López',50000),
            ('María', 'López', 40000),
            ('Pedro','Pérez', 30000),
            ('Eduardo','Campuzano', 10),
            ('Guillermo','Gallego',1000000000),
            ('Fulanito', 'de Tal', 100000000000)""")

conn.commit()

c.execute("SELECT * FROM empleados")

print(c.fetchall()) 

conn.close()
[('Juan', 'López', 50000), ('María', 'López', 40000), ('Pedro', 'Pérez', 30000), ('Eduardo', 'Campuzano', 10), ('Guillermo', 'Gallego', 1000000000), ('Fulanito', 'de Tal', 100000000000)]

Puedo hacer consultas

In [40]:
conn = sqlite3.connect(':memory:')
c= conn.cursor()

c.execute("""CREATE TABLE empleados(
nombre text,
apellido text,
sueldo integer
)
""")

c.execute("""INSERT INTO empleados VALUES 
            ('Juan','López',50000),
            ('María', 'López', 40000),
            ('Pedro','Pérez', 30000),
            ('Eduardo','Campuzano', 10),
            ('Guillermo','Gallego',1000000000),
            ('Fulanito', 'de Tal', 100000000000)""")

conn.commit()

c.execute("SELECT * FROM empleados WHERE apellido='López'")

print(c.fetchall()) 

conn.close()
[('Juan', 'López', 50000), ('María', 'López', 40000)]

Una forma interesante de interactuar con una base de datos es usando clases

In [41]:
class Empleado:
    def __init__(self,nombre,apellido,sueldo):
        self.nombre = nombre
        self.apellido = apellido
        self.sueldo = sueldo
In [44]:
conn = sqlite3.connect(':memory:')
c = conn.cursor()

emp1 = Empleado('Don', 'Nadie', 3000)
emp2 = Empleado('Doña', 'Nadie', 2000)

c.execute("""CREATE TABLE empleados(
nombre text,
apellido text,
sueldo integer
)""")

print(emp1.nombre)
print(emp1.apellido)
print(emp1.sueldo)

# Introduzco valores en la tabla:
c.execute("INSERT INTO empleados VALUES (:nombre,:apellido,:sueldo)",
         {'nombre':emp1.nombre, 'apellido':emp1.apellido, 'sueldo':emp1.sueldo})
conn.commit()

c.execute("INSERT INTO empleados VALUES (:nombre,:apellido,:sueldo)",
         {'nombre':emp2.nombre, 'apellido':emp2.apellido, 'sueldo':emp2.sueldo})
conn.commit()

# Hago una consulta: (los que tengan el mismo apellido que emp1)
c.execute("SELECT * FROM empleados WHERE apellido = :apellido",{'apellido':emp1.apellido})

print(c.fetchall()) 

conn.commit()
conn.close()
Don
Nadie
3000
[('Don', 'Nadie', 3000), ('Doña', 'Nadie', 2000)]

Voy a definir unas funciones para automatizar estos procedimientos

Una función para insertar empleados:

In [46]:
def insert_emp(emp):
    c.execute("INSERT INTO empleados VALUES (:nombre,:apellido,:sueldo)",
              {'nombre':emp.nombre,'apellido':emp.apellido, 'sueldo':emp.sueldo})

Una función que haga una consulta de los empleados por apellido:

In [80]:
def get_emps_by_name(apellido):
    c.execute("SELECT * FROM empleados WHERE apellido=:apellido", {'apellido':apellido})
    return c.fetchall()

Una función para actualizar el sueldo de un empleado:

In [50]:
def update_pay(emp, sueldo):
    emp.sueldo = sueldo
    c.execute("""UPDATE empleados SET sueldo = :sueldo
              WHERE nombre=:nombre AND apellido = :apellido""",
             {'sueldo':emp.sueldo,'nombre': emp.nombre, 'apellido': emp.apellido})

Una función para eliminar a un empleado:

In [54]:
def remove_emp(emp):
    c.execute("""DELETE FROM empleados WHERE nombre=:nombre AND apellido= :apellido""",
             {'nombre':emp.nombre, 'apellido':emp.apellido})

Vamos a usar las funciones que hemos definido:

In [90]:
conn=sqlite3.connect(':memory:')
c=conn.cursor()

c.execute("""CREATE TABLE empleados(
nombre text,
apellido text,
sueldo integer
)""")
Out[90]:
<sqlite3.Cursor at 0x7fbd8c179b90>

Me defino unos empleados:

In [91]:
emp0 = Empleado('Zutanito', 'Pérez', 10000)
In [92]:
lista_empleados = (Empleado('Juan','López',50000),
                                        Empleado('María', 'López', 40000),
                                        Empleado('Pedro','Pérez', 30000),
                                        Empleado('Eduardo','Campuzano', 10),
                                        Empleado('Guillermo','Gallego',1000000000),
                                        Empleado('Fulanito', 'de Tal', 100000000000))

Los introduzco en la base de datos:

In [93]:
insert_emp(emp0)
conn.commit()
In [94]:
for emp in lista_empleados:
    insert_emp(emp)
    conn.commit()
In [95]:
consulta_empleados = get_emps_by_name('Pérez')
print(consulta_empleados)
[('Zutanito', 'Pérez', 10000), ('Pedro', 'Pérez', 30000)]
In [96]:
consulta_empleados = get_emps_by_name('López')
print(consulta_empleados)
[('Juan', 'López', 50000), ('María', 'López', 40000)]
In [98]:
edu=lista_empleados[3]
In [99]:
update_pay(edu,3000000000)
In [100]:
consulta_empleados = get_emps_by_name('Campuzano')
print(consulta_empleados)
[('Eduardo', 'Campuzano', 3000000000)]
In [102]:
guille = lista_empleados[4]
guille.nombre
Out[102]:
'Guillermo'
In [103]:
remove_emp(guille)
In [104]:
c.execute("SELECT * FROM empleados")
print(c.fetchall())
[('Zutanito', 'Pérez', 10000), ('Juan', 'López', 50000), ('María', 'López', 40000), ('Pedro', 'Pérez', 30000), ('Eduardo', 'Campuzano', 3000000000), ('Fulanito', 'de Tal', 100000000000)]
In [105]:
conn.close()

Para que lo saque "bonito" podemos usar el paquete tabulate, que se instala con

pip install tabulate
In [106]:
from tabulate import tabulate
In [107]:
tabulate([('Alicia',24),('Bob',25)],headers=['Name','Age'], tablefmt='orgtbl')
Out[107]:
'| Name   |   Age |\n|--------+-------|\n| Alicia |    24 |\n| Bob    |    25 |'
In [108]:
print(tabulate([('Alicia',24),('Bob',25)],headers=['Name','Age'], tablefmt='orgtbl'))
| Name   |   Age |
|--------+-------|
| Alicia |    24 |
| Bob    |    25 |
In [115]:
conn=sqlite3.connect(':memory:')
c=conn.cursor()

c.execute("""CREATE TABLE empleados(
nombre text,
apellido text,
sueldo integer
)""")


lista_empleados = (Empleado('Juan','López',50000),
                                        Empleado('María', 'López', 40000),
                                        Empleado('Pedro','Pérez', 30000),
                                        Empleado('Eduardo','Campuzano', 10),
                                        Empleado('Guillermo','Gallego',1000000000),
                                        Empleado('Fulanito', 'de Tal', 100000000000))

for emp in lista_empleados:
    insert_emp(emp)
    
consulta=get_emps_by_name('López')
print(tabulate(consulta, headers=['Nombre', 'Apellido', 'Sueldo']))

print('\n')

update_pay(lista_empleados[1],90000)
remove_emp(lista_empleados[0])
consulta2 = get_emps_by_name('López')
print(tabulate(consulta2, headers=['Nombre', 'Apellido', 'Sueldo']))

conn.close()
Nombre    Apellido      Sueldo
--------  ----------  --------
Juan      López          50000
María     López          40000


Nombre    Apellido      Sueldo
--------  ----------  --------
María     López          90000
In [118]:
from IPython.display import display, Markdown

display(Markdown(tabulate(consulta, headers=['Nombre', 'Apellido', 'Sueldo'], tablefmt='github')))
Nombre Apellido Sueldo
Juan López 50000
María López 40000
In [ ]: