# SQLITE-UTILS 4.0: cách chúng ta đặt lại nền móng cho cơ sở dữ liệu

Đăng ngày: 2026-07-14

Trong thế giới phát triển phần mềm, việc cơ sở dữ liệu phải thay đổi theo thời gian là chuyện thường như cơm bữa. Schema cần được cập nhật, bảng biểu cần thêm cột, kiểu dữ liệu cần chỉnh sửa. Đây là một quá trình vừa cần thiết vừa tiềm ẩn rủi ro nếu không được quản lý bài bản. Mới đây, Simon Willison đã công bố sqlite-utils 4.0, một bản phát hành quan trọng thứ 124 của dự án và là lần tăng số phiên bản chính đầu tiên kể từ 3.0 vào tháng 11 năm 2020. Phiên bản này không chỉ mang đến vài thay đổi nhỏ nhưng đáng kể (được mô tả trong hướng dẫn nâng cấp) mà còn giới thiệu ba tính năng chính: cơ chế database migrations, hỗ trợ nested transactions thông qua phương thức db.atomic() mới, và khả năng sử dụng compound foreign keys. Trong ba tính năng mới, tôi tin database schema migrations là điểm nhấn lớn nhất. Tính năng này cho phép bạn định nghĩa một chuỗi các thay đổi cần thực hiện với cơ sở dữ liệu SQLite của mình, đồng thời có cơ chế theo dõi những thay đổi nào đã được áp dụng và những thay đổi nào còn đang chờ xử lý. Các migration được viết bằng file Python, tận dụng thư viện sqlite-utils với phương thức table.transform() cực kỳ mạnh mẽ. table.transform() giải quyết được những hạn chế của câu lệnh ALTER TABLE truyền thống của SQLite bằng cách tạo một bảng tạm với schema mới, sao chép dữ liệu, sau đó xóa bảng cũ và đổi tên bảng tạm thay thế – một phương pháp được chính tài liệu SQLite khuyến nghị. Chẳng hạn, bạn có thể tạo một bảng creatures, thêm cột weight, rồi đổi kiểu dữ liệu của species sang int và weight sang str theo từng bước rõ ràng thông qua các hàm được đánh dấu bằng @migrations(). Để áp dụng các migration này, tôi chỉ cần lưu chúng vào một file như migrations.py và chạy lệnh uvx sqlite-utils migrate data.db migrations.py. Hệ thống sẽ tự động tạo một bảng _sqlite_migrations để ghi lại những thay đổi đã chạy, giúp tôi dễ dàng kiểm soát lịch sử của cơ sở dữ liệu. Nếu không chỉ định file cụ thể, lệnh này thậm chí còn có thể quét thư mục hiện tại và các thư mục con để tìm các file migrations.py và áp dụng. Cá nhân tôi cũng đã áp dụng một phiên bản của mô hình này trong công cụ LLM của mình từ vài năm nay, thể hiện tính hiệu quả trong thực tế. So với các hệ thống migration phức tạp hơn như của Django (có thể tự động sinh code từ model hay rollback), cách tiếp cận của sqlite-utils đơn giản hơn nhiều: không tự động sinh migration (vì nó khuyến khích tạo bảng bằng code Python hơn là ORM model) và không có rollback tích hợp. Với SQLite, việc muốn quay lại phiên bản cũ chỉ đơn giản là sao chép file cơ sở dữ liệu trước khi chạy migration, một giải pháp thực dụng và dễ hiểu. Thực ra, thiết kế của sqlite-utils migrations đã có từ ba năm trước dưới dạng một package riêng tên sqlite-migrate, nhưng chưa bao giờ thoát khỏi giai đoạn beta. Việc đưa nó vào sqlite-utils 4.0 là một động thái chiến lược, biến nó thành tính năng mặc định trong hệ sinh thái ngày càng lớn mạnh của sqlite-utils/Datasette/LLM. Bên cạnh đó, phiên bản 4.0 cũng giải quyết "mối quan hệ lộn xộn" trước đây của thư viện với các giao dịch cơ sở dữ liệu bằng cách giới thiệu hỗ trợ nested transactions thông qua db.atomic(). Với tôi, những nâng cấp này không chỉ là những dòng code mới; chúng là những công cụ giúp chúng ta quản lý sự phức tạp của dữ liệu một cách có cấu trúc hơn, giảm thiểu rủi ro và đảm bảo rằng hệ thống của chúng ta có thể tiến hóa một cách ổn định theo thời gian, dù là với những dự án nhỏ hay những hệ thống lớn đang trên đà phát triển.

Canonical: https://www.tungpham.vn/blog/sqlite-utils-40-cach-chung-ta-dat-lai-nen-mong-cho-co-so-du-lieu
