Manipulación de datos con el ORM#
Ultima modificación: Mar 6, 2024 | YouTube
Preparación#
[1]:
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.orm import declarative_base, relationship
Base = declarative_base()
class User(Base):
__tablename__ = "user_account"
id = Column(Integer, primary_key=True)
name = Column(String(30))
fullname = Column(String)
addresses = relationship(
"Address", back_populates="user", cascade="all, delete-orphan"
)
def __repr__(self):
return f"User(id={self.id!r}, name={self.name!r}, fullname={self.fullname!r})"
class Address(Base):
__tablename__ = "address"
id = Column(Integer, primary_key=True)
email_address = Column(String, nullable=False)
user_id = Column(Integer, ForeignKey("user_account.id"), nullable=False)
user = relationship("User", back_populates="addresses")
def __repr__(self):
return f"Address(id={self.id!r}, email_address={self.email_address!r})"
[2]:
from sqlalchemy import create_engine
engine = create_engine(
"sqlite+pysqlite:///:memory:",
echo=False,
future=True,
)
[3]:
Base.metadata.create_all(engine)
[4]:
from sqlalchemy.orm import Session
with Session(engine) as session:
spongebob = User(
name="spongebob",
fullname="Spongebob Squarepants",
addresses=[Address(email_address="spongebob@sqlalchemy.org")],
)
sandy = User(
name="sandy",
fullname="Sandy Cheeks",
addresses=[
Address(email_address="sandy@sqlalchemy.org"),
Address(email_address="sandy@squirrelpower.org"),
],
)
patrick = User(
name="patrick",
fullname="Patrick Star",
)
session.add_all(
[
spongebob,
sandy,
patrick,
]
)
session.commit()
Adición de objetos a una sesión#
[5]:
squidward = User(name="squidward", fullname="Squidward Tentacles")
krabs = User(name="ehkrabs", fullname="Eugene H. Krabs")
[6]:
squidward
[6]:
User(id=None, name='squidward', fullname='Squidward Tentacles')
[7]:
krabs
[7]:
User(id=None, name='ehkrabs', fullname='Eugene H. Krabs')
[8]:
session = Session(engine)
session.add(squidward)
session.add(krabs)
#
# Los objetos pendientes por insertar se ven en session.new
#
session.new
[8]:
IdentitySet([User(id=None, name='squidward', fullname='Squidward Tentacles'), User(id=None, name='ehkrabs', fullname='Eugene H. Krabs')])
[9]:
#
# Cuando se emiten los cambios a la BD se hace un flush.
#
session.flush()
[10]:
#
# No hay cambios pendientes
#
session.new
[10]:
IdentitySet([])
Claves primarias autogeneradas#
[11]:
squidward.id
[11]:
4
[12]:
krabs.id
[12]:
5
Obtención de objetos por la clave primaria#
[13]:
some_squidward = session.get(User, 4)
some_squidward
[13]:
User(id=4, name='squidward', fullname='Squidward Tentacles')
[14]:
some_squidward is squidward
[14]:
True
Commiting#
[15]:
session.commit()
Actualización de objetos#
[16]:
from sqlalchemy import select
sandy = session.execute(select(User).filter_by(name="sandy")).scalar_one()
sandy
[16]:
User(id=2, name='sandy', fullname='Sandy Cheeks')
[17]:
#
# Se altera el atributo de un objeto
#
sandy.fullname = "Sandy Squirrel"
[18]:
#
# El objeto pertenece a una colección "dirty"
#
sandy in session.dirty
[18]:
True
[19]:
sandy_fullname = session.execute(select(User.fullname).where(User.id == 2)).scalar_one()
print(sandy_fullname)
Sandy Squirrel
[20]:
sandy in session.dirty
[20]:
False
UPDATE en el ORM#
[21]:
from sqlalchemy import update
session.execute(
update(User)
.where(User.name == "sandy")
.values(fullname="Sandy Squirrel Extraordinaire")
)
[21]:
<sqlalchemy.engine.cursor.CursorResult at 0x110b6a4c0>
[22]:
sandy.fullname
[22]:
'Sandy Squirrel Extraordinaire'
Borrado de objetos ORM#
[23]:
patrick = session.get(User, 3)
[24]:
session.delete(patrick)
[25]:
session.execute(select(User).where(User.name == "patrick")).first()
[26]:
patrick in session
[26]:
False
[27]:
from sqlalchemy import delete
squidward = session.get(User, 4)
session.execute(delete(User).where(User.name == "squidward"))
[27]:
<sqlalchemy.engine.cursor.CursorResult at 0x110b88ac0>
[28]:
squidward in session
[28]:
False
Rolling back#
[29]:
session.rollback()
[30]:
sandy.__dict__
[30]:
{'_sa_instance_state': <sqlalchemy.orm.state.InstanceState at 0x110b464c0>}
[31]:
sandy.fullname
[31]:
'Sandy Cheeks'
[32]:
sandy.__dict__
[32]:
{'_sa_instance_state': <sqlalchemy.orm.state.InstanceState at 0x110b464c0>,
'id': 2,
'name': 'sandy',
'fullname': 'Sandy Cheeks'}
[33]:
patrick in session
[33]:
True
[34]:
session.execute(select(User).where(User.name == "patrick")).scalar_one() is patrick
[34]:
True
Cerrado de una sesión#
[35]:
session.close()