SQLAlchemy Core - Sử dụng nhiều bảng

Một trong những tính năng quan trọng của RDBMS là thiết lập mối quan hệ giữa các bảng. Các hoạt động SQL như SELECT, UPDATE và DELETE có thể được thực hiện trên các bảng liên quan. Phần này mô tả các thao tác này bằng SQLAlchemy.

Vì mục đích này, hai bảng được tạo trong cơ sở dữ liệu SQLite của chúng tôi (college.db). Bảng sinh viên có cấu trúc tương tự như đã cho trong phần trước; trong khi bảng địa chỉ cóst_id cột được ánh xạ tới id column in students table sử dụng ràng buộc khóa ngoại.

Đoạn mã sau sẽ tạo hai bảng trong 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)

Đoạn mã trên sẽ dịch sang truy vấn TẠO BẢNG cho sinh viên và bảng địa chỉ như bên dưới -

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)
)

Các ảnh chụp màn hình sau đây trình bày đoạn mã trên rất rõ ràng -

Các bảng này được điền dữ liệu bằng cách thực thi insert() methodcủa các đối tượng bảng. Để chèn 5 hàng trong bảng sinh viên, bạn có thể sử dụng mã được cung cấp bên dưới:

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 được thêm vào bảng địa chỉ với sự trợ giúp của mã sau:

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]'},
])

Lưu ý rằng cột st_id trong bảng địa chỉ tham chiếu đến cột id trong bảng sinh viên. Bây giờ chúng ta có thể sử dụng mối quan hệ này để tìm nạp dữ liệu từ cả hai bảng. Chúng tôi muốn tìm nạpnamelastname từ bảng sinh viên tương ứng với st_id trong bảng địa chỉ.

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)

Các đối tượng được chọn sẽ dịch một cách hiệu quả thành biểu thức SQL sau khi nối hai bảng trên quan hệ chung:

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

Điều này sẽ tạo ra kết quả trích xuất dữ liệu tương ứng từ cả hai bảng như sau:

(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]')