Trabajo con Transacciones y el DBAPI#
Ultima modificación: Mar 6, 2024 | YouTube
Preparación#
[1]:
from sqlalchemy import create_engine
engine = create_engine(
"sqlite+pysqlite:///:memory:",
echo=True,
future=True,
)
Envio de comandos SQL al motor de la base de datos#
[2]:
#
# El paquete text permite crear consultas en el lenguaje SQL
#
from sqlalchemy import text
with engine.connect() as conn:
result = conn.execute(text("select 'hello world'"))
print(result.all())
2022-09-13 11:24:50,037 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-09-13 11:24:50,048 INFO sqlalchemy.engine.Engine select 'hello world'
2022-09-13 11:24:50,049 INFO sqlalchemy.engine.Engine [generated in 0.01197s] ()
[('hello world',)]
2022-09-13 11:24:50,050 INFO sqlalchemy.engine.Engine ROLLBACK
Estilo “commit as you go”#
[3]:
with engine.connect() as conn:
conn.execute(text("CREATE TABLE some_table (x int, y int)"))
conn.execute(
text("INSERT INTO some_table (x, y) VALUES (:x, :y)"),
[
{"x": 1, "y": 1},
{"x": 2, "y": 4},
],
)
conn.commit() # confirmar los cambios hasta aca
2022-09-13 11:24:50,191 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-09-13 11:24:50,192 INFO sqlalchemy.engine.Engine CREATE TABLE some_table (x int, y int)
2022-09-13 11:24:50,193 INFO sqlalchemy.engine.Engine [generated in 0.00186s] ()
2022-09-13 11:24:50,194 INFO sqlalchemy.engine.Engine INSERT INTO some_table (x, y) VALUES (?, ?)
2022-09-13 11:24:50,194 INFO sqlalchemy.engine.Engine [generated in 0.00051s] ((1, 1), (2, 4))
2022-09-13 11:24:50,195 INFO sqlalchemy.engine.Engine COMMIT
Estilo “begin once” (modo preferido en la práctica)#
[4]:
#
# El commit es automático cuando se termina el bloque with.
# Hay un rollback automático en caso de falla del bloque with.
#
with engine.begin() as conn:
conn.execute(
text("INSERT INTO some_table (x, y) VALUES (:x, :y)"),
[
{"x": 6, "y": 8},
{"x": 9, "y": 10},
],
)
2022-09-13 11:24:50,311 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-09-13 11:24:50,312 INFO sqlalchemy.engine.Engine INSERT INTO some_table (x, y) VALUES (?, ?)
2022-09-13 11:24:50,313 INFO sqlalchemy.engine.Engine [cached since 0.1189s ago] ((6, 8), (9, 10))
2022-09-13 11:24:50,314 INFO sqlalchemy.engine.Engine COMMIT
Extracción de filas#
[5]:
with engine.connect() as conn:
# Result es un objeto interactivo de tipo ResultProxy
result = conn.execute(text("SELECT x, y FROM some_table"))
# Iteracion sobre los nombres de los atributos del objeto
for row in result:
print(f"x: {row.x} y: {row.y}")
2022-09-13 11:24:50,371 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-09-13 11:24:50,373 INFO sqlalchemy.engine.Engine SELECT x, y FROM some_table
2022-09-13 11:24:50,373 INFO sqlalchemy.engine.Engine [generated in 0.00182s] ()
x: 1 y: 1
x: 2 y: 4
x: 6 y: 8
x: 9 y: 10
2022-09-13 11:24:50,374 INFO sqlalchemy.engine.Engine ROLLBACK
[6]:
with engine.connect() as conn:
result = conn.execute(text("SELECT x, y FROM some_table"))
# Iteracion sobre la tupla
for x, y in result:
print(f"x: {x} y: {y}")
2022-09-13 11:24:50,424 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-09-13 11:24:50,425 INFO sqlalchemy.engine.Engine SELECT x, y FROM some_table
2022-09-13 11:24:50,425 INFO sqlalchemy.engine.Engine [cached since 0.05422s ago] ()
x: 1 y: 1
x: 2 y: 4
x: 6 y: 8
x: 9 y: 10
2022-09-13 11:24:50,426 INFO sqlalchemy.engine.Engine ROLLBACK
[7]:
with engine.connect() as conn:
result = conn.execute(text("SELECT x, y FROM some_table"))
# Iteracion sobre los indices de los elementos en el objeto
for row in result:
print(f"x: {row[0]} y: {row[1]}")
2022-09-13 11:24:50,470 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-09-13 11:24:50,471 INFO sqlalchemy.engine.Engine SELECT x, y FROM some_table
2022-09-13 11:24:50,472 INFO sqlalchemy.engine.Engine [cached since 0.1004s ago] ()
x: 1 y: 1
x: 2 y: 4
x: 6 y: 8
x: 9 y: 10
2022-09-13 11:24:50,473 INFO sqlalchemy.engine.Engine ROLLBACK
[8]:
with engine.connect() as conn:
result = conn.execute(text("SELECT x, y FROM some_table"))
# Iteracion como mapping
for dict_row in result.mappings():
x = dict_row["x"]
y = dict_row["y"]
print(f"x: {x} y: {y}")
2022-09-13 11:24:50,515 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-09-13 11:24:50,516 INFO sqlalchemy.engine.Engine SELECT x, y FROM some_table
2022-09-13 11:24:50,517 INFO sqlalchemy.engine.Engine [cached since 0.1456s ago] ()
x: 1 y: 1
x: 2 y: 4
x: 6 y: 8
x: 9 y: 10
2022-09-13 11:24:50,518 INFO sqlalchemy.engine.Engine ROLLBACK
Envio de un grupo de parámetros#
[9]:
with engine.connect() as conn:
result = conn.execute(
text(
"SELECT x, y FROM some_table WHERE y > :z"
), # note el uso de :z al final del string
{"z": 2}, # diccionario con los valores de los parametros
)
for row in result:
print(f"x: {row.x} y: {row.y}")
2022-09-13 11:24:50,557 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-09-13 11:24:50,558 INFO sqlalchemy.engine.Engine SELECT x, y FROM some_table WHERE y > ?
2022-09-13 11:24:50,558 INFO sqlalchemy.engine.Engine [generated in 0.00153s] (2,)
x: 2 y: 4
x: 6 y: 8
x: 9 y: 10
2022-09-13 11:24:50,560 INFO sqlalchemy.engine.Engine ROLLBACK
Envio de múltiples grupos de parámetros#
[10]:
with engine.connect() as conn:
conn.execute(
text("INSERT INTO some_table (x, y) VALUES (:x, :y)"),
[
{"x": 11, "y": 12},
{"x": 13, "y": 14},
],
)
conn.commit()
2022-09-13 11:24:50,636 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-09-13 11:24:50,637 INFO sqlalchemy.engine.Engine INSERT INTO some_table (x, y) VALUES (?, ?)
2022-09-13 11:24:50,637 INFO sqlalchemy.engine.Engine [cached since 0.4433s ago] ((11, 12), (13, 14))
2022-09-13 11:24:50,638 INFO sqlalchemy.engine.Engine COMMIT
Empaquetado#
[11]:
stmt = text("SELECT x, y FROM some_table WHERE y > :z ORDER BY x, y").bindparams(z=6)
with engine.connect() as conn:
result = conn.execute(stmt)
for row in result:
print(f"x: {row.x} y: {row.y}")
2022-09-13 11:24:50,714 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-09-13 11:24:50,715 INFO sqlalchemy.engine.Engine SELECT x, y FROM some_table WHERE y > ? ORDER BY x, y
2022-09-13 11:24:50,715 INFO sqlalchemy.engine.Engine [generated in 0.00158s] (6,)
x: 6 y: 8
x: 9 y: 10
x: 11 y: 12
x: 13 y: 14
2022-09-13 11:24:50,716 INFO sqlalchemy.engine.Engine ROLLBACK
Ejecución con una sesión ORM#
[12]:
from sqlalchemy.orm import Session
stmt = text("SELECT x, y FROM some_table WHERE y > :z ORDER BY x, y").bindparams(z=6)
with Session(engine) as session:
result = session.execute(stmt)
for row in result:
print(f"x: {row.x} y: {row.y}")
2022-09-13 11:24:50,814 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-09-13 11:24:50,815 INFO sqlalchemy.engine.Engine SELECT x, y FROM some_table WHERE y > ? ORDER BY x, y
2022-09-13 11:24:50,815 INFO sqlalchemy.engine.Engine [cached since 0.1014s ago] (6,)
x: 6 y: 8
x: 9 y: 10
x: 11 y: 12
x: 13 y: 14
2022-09-13 11:24:50,816 INFO sqlalchemy.engine.Engine ROLLBACK
[13]:
#
# Sesion usa "commit as you go" por defecto
#
with Session(engine) as session:
result = session.execute(
text("UPDATE some_table SET y=:y WHERE x=:x"),
[
{"x": 9, "y": 11},
{"x": 13, "y": 15},
],
)
session.commit()
2022-09-13 11:24:50,853 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2022-09-13 11:24:50,854 INFO sqlalchemy.engine.Engine UPDATE some_table SET y=? WHERE x=?
2022-09-13 11:24:50,855 INFO sqlalchemy.engine.Engine [generated in 0.00063s] ((11, 9), (15, 13))
2022-09-13 11:24:50,856 INFO sqlalchemy.engine.Engine COMMIT