SQLAlchemy ORM là gì?
SQLAlchemy ORM (Object-Relational Mapping) là một trong những thư viện ORM hàng đầu cho Python, cung cấp cách thức hiệu quả và linh hoạt để tương tác với cơ sở dữ liệu.
1. Cài đặt SQLAlchemy
Đầu tiên, bạn cần cài đặt SQLAlchemy và trình điều khiển thích hợp cho loại cơ sở dữ liệu mà bạn muốn sử dụng:
pip install sqlalchemy
Trình điều khiển cho các loại CSDL phổ biến:
# PostgreSQL
pip install psycopg2-binary
# MySQL
pip install mysql-connector-python
# SQLite (đã được tích hợp sẵn)
2. Các khái niệm cơ bản
- Engine: Biểu diễn kết nối đến cơ sở dữ liệu
- Session: Quản lý các phiên làm việc và thao tác dữ liệu
- Model: Lớp định nghĩa cấu trúc bảng trong CSDL
- Query: Đối tượng để xây dựng và thực thi các truy vấn
3. Kết nối đến cơ sở dữ liệu
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
# Kết nối SQLite
engine = create_engine('sqlite:///thuvien.db', echo=True)
# Kết nối PostgreSQL
# engine = create_engine('postgresql://username:password@localhost:5432/mydb')
# Kết nối MySQL
# engine = create_engine('mysql+mysqlconnector://username:password@localhost:3306/mydb')
# Tạo phiên làm việc
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
session = SessionLocal()
4. Định nghĩa模型 và bảng
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, declarative_base
Base = declarative_base()
class SinhVien(Base):
__tablename__ = 'sinh_vien'
id = Column(Integer, primary_key=True, index=True)
ten = Column(String(50), nullable=False)
email = Column(String(100), unique=True, index=True)
bai_viets = relationship("BaiViet", back_populates="tac_gia")
class BaiViet(Base):
__tablename__ = 'bai_viet'
id = Column(Integer, primary_key=True, index=True)
tieu_de = Column(String(100), nullable=False)
noi_dung = Column(String(500))
sinh_vien_id = Column(Integer, ForeignKey('sinh_vien.id'))
tac_gia = relationship("SinhVien", back_populates="bai_viets")
thung muc = relationship("ThuMuc", secondary="bai_viet_thu_muc", back_populates="bai_viets")
class ThuMuc(Base):
__tablename__ = 'thu_muc'
id = Column(Integer, primary_key=True, index=True)
ten = Column(String(30), unique=True, nullable=False)
bai_viets = relationship("BaiViet", secondary="bai_viet_thu_muc", back_populates="thung muc")
class BaiVietThuMuc(Base):
__tablename__ = 'bai_viet_thu_muc'
bai_viet_id = Column(Integer, ForeignKey('bai_viet.id'), primary_key=True)
thu_muc_id = Column(Integer, ForeignKey('thu_muc.id'), primary_key=True)
5. Tạo bảng trong CSDL
Base.metadata.create_all(bind=engine)
6. Thực hiện các thao tác CRUD cơ bản
6.1. Tạo dữ liệu
# Tạo sinh viên mới
new_student = SinhVien(ten="Nguyễn Văn A", email="hangsan@thuvien.com")
session.add(new_student)
session.commit()
# Tạo nhiều sinh viên cùng lúc
session.add_all([
SinhVien(ten="Trần Thị B", email="tranthib@example.com"),
SinhVien(ten="Lê Công C", email="lecong@example.com")
])
session.commit()
6.2. Đọc dữ liệu
# Lấy tất cả sinh viên
students = session.query(SinhVien).all()
# Lấy sinh viên đầu tiên
first_student = session.query(SinhVien).first()
# Lấy sinh viên theo ID
student = session.query(SinhVien).get(1)
6.3. Cập nhật dữ liệu
# Cập nhật thông tin sinh viên
student = session.query(SinhVien).get(1)
student.ten = "Nguyễn Văn A1"
session.commit()
# Cập nhật nhiều sinh viên
session.query(SinhVien).filter(SinhVien.ten.like("Nguyễn%")).update({SinhVien.ten: "Nguyễn氏"}, synchronize_session=False)
session.commit()
6.4. Xoá dữ liệu
# Xoá sinh viên theo ID
student = session.query(SinhVien).get(1)
session.delete(student)
session.commit()
# Xoá nhiều sinh viên
session.query(SinhVien).filter(SinhVien.ten == "Trần Thị B").delete(synchronize_session=False)
session.commit()
7. Quản lý quan hệ dữ liệu
# Tạo sinh viên và bài viết liên quan
student = SinhVien(ten="Phạm Văn D", email="phamvan@example.com")
article = BaiViet(tieu_de="Toán cao cấp", noi_dung="Phương trình...", tac_gia=student)
session.add(article)
session.commit()
# Truy cập thông qua quan hệ
print(f"Bài viết '{article.tieu_de}' được viết bởi {article.tac_gia.ten}")
# Thêm nhiều mục từ vào bài viết
math_tag = ThuMuc(ten="Toán")
physics_tag = ThuMuc(ten="Vật lý")
article.thung muc.append(math_tag)
article.thung muc.append(physics_tag)
session.commit()
8. Quản lý giao dịch
try:
student = SinhVien(ten="Hà Thị E", email="hathie@example.com")
session.add(student)
session.commit()
except Exception as e:
session.rollback()
print(f"Lỗi: {e}")
9. Thực hành tốt
- Tạo mới phiên làm việc cho mỗi yêu cầu
- Phải xử lý ngoại lệ và rollback giao dịch
- TránhLoad N+1 bằng cách sử dụng eager loading
- Điều chỉnhpool kết nối phù hợp
- Thực hiện kiểm tra dữ liệu đầu vào
10. Kết luận
Bài viết này đã hướng dẫn bạn cách:
- Cài đặt và cấu hình SQLAlchemy ORM
- Định nghĩa các model và quan hệ
- Thực hiện các thao tác CRUD cơ bản
- Xây dựng các truy vấn phức tạp
- Quản lý các giao dịch trong CSDL
- Áp dụng các thực hành tốt nhất
SQLAlchemy ORM còn nhiều tính năng cao cấp khác như thuộc tính混 hợp, lắng nghe sự kiện, và các truy vấn tùy chỉnh mà bạn có thể tìm hiểu thêm.