SQLAlchemy Core: uso de varias tablas
Una de las características importantes de RDBMS es establecer una relación entre tablas. Las operaciones SQL como SELECT, UPDATE y DELETE se pueden realizar en tablas relacionadas. Esta sección describe estas operaciones usando SQLAlchemy.
Para ello, se crean dos tablas en nuestra base de datos SQLite (college.db). La tabla de estudiantes tiene la misma estructura que la dada en la sección anterior; mientras que la tabla de direcciones tienest_id columna que se asigna a id column in students table usando restricción de clave externa.
El siguiente código creará dos tablas en college.db:
from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String, ForeignKey
engine = create_engine('sqlite:///college.db', echo=True)
meta = MetaData()
students = Table(
'students', meta,
Column('id', Integer, primary_key = True),
Column('name', String),
Column('lastname', String),
)
addresses = Table(
'addresses', meta,
Column('id', Integer, primary_key = True),
Column('st_id', Integer, ForeignKey('students.id')),
Column('postal_add', String),
Column('email_add', String))
meta.create_all(engine)
El código anterior se traducirá en consultas CREATE TABLE para estudiantes y en la tabla de direcciones como se muestra a continuación:
CREATE TABLE students (
id INTEGER NOT NULL,
name VARCHAR,
lastname VARCHAR,
PRIMARY KEY (id)
)
CREATE TABLE addresses (
id INTEGER NOT NULL,
st_id INTEGER,
postal_add VARCHAR,
email_add VARCHAR,
PRIMARY KEY (id),
FOREIGN KEY(st_id) REFERENCES students (id)
)
Las siguientes capturas de pantalla presentan el código anterior de manera muy clara:
Estas tablas se completan con datos ejecutando insert() methodde objetos de mesa. Para insertar 5 filas en la tabla de estudiantes, puede usar el código que se proporciona a continuación:
from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String
engine = create_engine('sqlite:///college.db', echo = True)
meta = MetaData()
conn = engine.connect()
students = Table(
'students', meta,
Column('id', Integer, primary_key = True),
Column('name', String),
Column('lastname', String),
)
conn.execute(students.insert(), [
{'name':'Ravi', 'lastname':'Kapoor'},
{'name':'Rajiv', 'lastname' : 'Khanna'},
{'name':'Komal','lastname' : 'Bhandari'},
{'name':'Abdul','lastname' : 'Sattar'},
{'name':'Priya','lastname' : 'Rajhans'},
])
Rows se agregan en la tabla de direcciones con la ayuda del siguiente código:
from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String
engine = create_engine('sqlite:///college.db', echo = True)
meta = MetaData()
conn = engine.connect()
addresses = Table(
'addresses', meta,
Column('id', Integer, primary_key = True),
Column('st_id', Integer),
Column('postal_add', String),
Column('email_add', String)
)
conn.execute(addresses.insert(), [
{'st_id':1, 'postal_add':'Shivajinagar Pune', 'email_add':'[email protected]'},
{'st_id':1, 'postal_add':'ChurchGate Mumbai', 'email_add':'[email protected]'},
{'st_id':3, 'postal_add':'Jubilee Hills Hyderabad', 'email_add':'[email protected]'},
{'st_id':5, 'postal_add':'MG Road Bangaluru', 'email_add':'[email protected]'},
{'st_id':2, 'postal_add':'Cannought Place new Delhi', 'email_add':'[email protected]'},
])
Tenga en cuenta que la columna st_id en la tabla de direcciones se refiere a la columna de identificación en la tabla de estudiantes. Ahora podemos usar esta relación para obtener datos de ambas tablas. Queremos ir a buscarname y lastname de la tabla de estudiantes correspondiente a st_id en la tabla de direcciones.
from sqlalchemy.sql import select
s = select([students, addresses]).where(students.c.id == addresses.c.st_id)
result = conn.execute(s)
for row in result:
print (row)
Los objetos seleccionados se traducirán efectivamente en la siguiente expresión SQL que une dos tablas en relación común:
SELECT students.id,
students.name,
students.lastname,
addresses.id,
addresses.st_id,
addresses.postal_add,
addresses.email_add
FROM students, addresses
WHERE students.id = addresses.st_id
Esto producirá una salida extrayendo los datos correspondientes de ambas tablas de la siguiente manera:
(1, 'Ravi', 'Kapoor', 1, 1, 'Shivajinagar Pune', '[email protected]')
(1, 'Ravi', 'Kapoor', 2, 1, 'ChurchGate Mumbai', '[email protected]')
(3, 'Komal', 'Bhandari', 3, 3, 'Jubilee Hills Hyderabad', '[email protected]')
(5, 'Priya', 'Rajhans', 4, 5, 'MG Road Bangaluru', '[email protected]')
(2, 'Rajiv', 'Khanna', 5, 2, 'Cannought Place new Delhi', '[email protected]')