Hướng dẫn dùng sqlalchemy flask python
Trong phần này, chúng ta sẽ cùng tìm hiểu về cách sử dụng cơ sở dữ liệu với ứng dụng Flask. Show Để giúp cho bạn dễ theo dõi, sau đây là danh sách các bài viết trong loạt bài hướng dẫn này:
Bạn có thể truy cập mã nguồn cho phần này tại GitHub. Đây là một phần rất quan trọng vì hầu hết các ứng dụng đều cần đọc và lưu trữ dữ liệu một cách hiệu quả. Vì thế, chúng ta cần phải dùng đến cơ sở dữ liệu cho mục đích này. Nếu bạn có tìm hiểu qua, bạn sẽ biết rằng Flask không hỗ trợ sẵn cơ sở dữ liệu. Tuy nhiên đây không phải là do sơ sót mà Flask được thiết kế như vậy để cho phép bạn chọn cơ sở dữ liệu nào thích hợp nhất cho ứng dụng của bạn thay vì bắt buộc bạn phải dùng một hệ cơ sở dữ liệu nào đó. Các thư viện mở rộng trong Flask hỗ trợ cho việc sử dụng nhiều cơ sở dữ liệu khác nhau. Các hệ cơ sở dữ liệu có thể được chia thành hai nhóm chính: nhóm cơ sở dữ liệu theo mô hình quan hệ (relational) và nhóm còn lại không sử dụng mô hình này. Nhóm sau cũng được biết với tên gọi NoSQL bởi vì các hệ cơ sở dữ liệu trong nhóm này không sử dụng ngôn ngữ hỏi đáp SQL nối tiếng. Mặc dù cả hai nhóm đều có các đại diện xuất sắc, các hệ cơ sở dữ liệu trong nhóm đầu thích hợp hơn với các dữ liệu có cấu trúc như là danh sách người sử dụng, các bài viết … trong khi NoSQL thích hợp cho dữ liệu không có cấu trúc chặt chẽ. Ứng dụng của chúng ta có thể sử dụng các hệ cơ sở dữ liệu trong cả hai nhóm, nhưng chúng ta sẽ chọn cơ sở dữ liệu quan hệ theo như lý do đã nói ở trên. Trong Phần 3, chúng ta đã sử dụng thư viện mở rộng đầu tiên trong Flask (còn nhớ Flask-WTF không?). Trong phần này, chúng ta sẽ sử dụng thêm hai thư viện mở rộng nữa. Thư viện đầu tiên là Flask-SQLAlchemy. Đây là một thư viện cho phép chúng ta sử dụng một gói rất phổ biến là SQLAlchemy. Đây là một phần mềm trong nhóm sản phẩm gọi là Object Relational Mapping hay ORM. Các phần mềm trong nhóm này giúp chúng ta giao tiếp với cơ sở dữ liệu thông qua các thực thể như lớp, đối tượng và phương thức thay vi dùng các bảng và ngôn ngữ SQL (Các đại diện tiêu biểu cho nhóm sản phẩm này gồm có Hibernate cho Java, NHibernate hoặc EntityFramework cho .NET framework, …). Công việc chính của các phần mềm ORM là dịch các tác vụ bậc cao thành các lệnh dùng trong cơ sở dữ liệu. Một đặc điểm rất hay của SQLAlchemy là nó hỗ trợ cho rất nhiều cơ sở dữ liệu quan hệ khác nhau như MySQL, PostgreSQL và SQLite. Điều này rất hữu ích vì nó có nghĩa là bạn có thể phát triển ứng dụng với một hệ cơ sở dữ liệu đơn giản như SQLite – vốn không đòi hỏi việc cài đặt phức tạp, nhưng khi triển khai ứng dụng, bạn có thể chuyển sang một hệ cơ sở dữ liệu khác tốt hơn như là MySQL hay PostgreSQL mà không cần phải thay đổi mã trong ứng dụng của bạn. Để cài đặt Flask-SQLAlchemy trong môi trường ảo của bạn, hãy kích hoạt nó và chạy lệnh sau:
Chuyển đổi dữ liệuPhần lớn các bài hướng dẫn về cơ sở dữ liệu chỉ dạy cách tạo và sử dụng chúng nhưng lại không đề cập đến vấn đề làm sao để cập nhật cấu trúc của cơ sở dữ liệu sẵn có khi ứng dụng thay đổi. Điều này khó thực hiện bởi vì các thiết kế cơ sở dữ liệu quan hệ có liên quan chặt chẽ đến cấu trúc của dữ liệu. Khi cấu trúc của dữ liệu thay đổi, cơ sở dữ liệu cũng phải được chuyển đổi để thích ứng với cấu trúc mới. Thư viện mở rộng thứ hai mà chúng ta sẽ sử dụng là Flask-Migrate. Thư viện này là một giao diện của Flask với Alembic – một framework chuyên cho viện chuyển đổi dữ liệu với SQLAlchemy. Việc chuyển đổi cơ sở dữ liệu sẽ làm cho chúng ta mất công hơn một chút khi khởi tạo cơ sở dữ liệu, nhưng đáng giá vì nó sẽ giảm nhiều gánh nặng cho chúng ta trong việc thay đổi cơ sở dữ liệu trong tượng lai. Quá trình cài đặt thư viện Flask-Migrate hoàn toàn tương tự như các thư viện khác:
Thiết lập cấu hình cho Flask-SQLAlchemyChúng ta sẽ sử dụng cơ sở dữ liệu SQLite cho ứng dụng của chúng ta. SQLite là một hệ cơ sở dữ liệu được sử dụng rộng rãi trong quá trình phát triển các ứng dụng nhỏ hoặc thậm chí một vài ứng dụng lớn. Với SQLite, mỗi cơ sở dữ liệu sẽ được lưu trữ trong một file duy nhất và không đòi hỏi phải cài đặt thêm các phần mềm khác trên máy chủ như trong trường hợp của MySQL và PostgreSQL. Chúng ta sẽ phải thêm vào một số cấu hình mới trong file config.py: config.py: Cấu hình cho Flask-SQLAlchemy
Thư viện Flask-SQLAlchemy sẽ sử dụng cơ sở dữ liệu tại URL được chỉ định bởi tham số cấu hình Tham số Trong ứng dụng của chúng ta, cơ sở dữ liệu sẽ được đại diện bởi một đối tượng gọi là thực thể cơ sở dữ liệu (database instance). Thành phần đảm nhiệm việc chuyển đổi cơ sở dữ liệu cũng sẽ được đại diện bởi một đối tượng khác. Các đối tượng này cần được khởi tạo trong ứng dụng, cụ thể hơn là trong file app/__init__.py: app/__init__.py: Khởi tạo các đối tượng Flask-SQLAlchemy và Flask-Migrate
Chúng ta thay đổi ba chỗ trong mã ở trên. Đầu tiên, chúng ta thêm một đối tượng tên là Mô hình dữ liệuDữ liệu trong các hệ thống cơ sở dữ liệu sẽ được đại diện bởi một tập hợp các lớp, thường được gọi là mô hình dữ liệu (database model). Lớp ORM bên trong của SQLAlchemy sẽ thực hiện các công việc chuyển đổi cần thiết để ánh xạ các đối tượng từ mô hình dữ liệu vào các hàng và bảng trong cơ sở dữ liệu. Để bắt đầu, chúng ta hãy thử tạo một mô hình cho người sử dụng theo như sơ đồ sau: Trường Các trường Bây giờ, chúng ta có thể chuyển đổi mô hình dữ liệu người dùng ở trên thành mã chương trình trong file app/models như sau: app/models.py: Mô hình dữ liệu về người sử dụng
Lớp Phương thức
Tạo ra kho lưu trữ cho quá trình chuyển đổi dữ liệu (migration repository)Mô hình dữ liệu mà chúng ta tạo ra ở trên định nghĩa cấu trúc ban đầu của dữ liệu (schema) mà chúng ta sẽ dùng trong ứng dụng. Nhưng khi chúng ta tiếp tục phát triển ứng dụng về sau, sẽ có những lúc chúng ta sẽ cần thay đổi hay cập nhật cấu trúc này. Để giúp cho quá trình này, Alembic (framework cho việc chuyển đổi dữ liệu được sử dụng trong thư viện Flask-Migrate) sẽ đảm nhiệm việc thay đổi cấu trúc dữ liệu trong cơ sở dữ liệu mà không cần phải tạo lại cơ sở dữ liệu từ đầu. Để thực thi công việc có vẻ khó khăn này, Alembic có một kho lưu trữ cho quá trình chuyển đổi dữ liệu (migration repository). Đây thực ra là một thư mục có chứa các đoạn mã kịch bản (script) cho việc chuyển đổi dữ liệu. Mỗi khi chúng ta cập nhật cấu trúc dữ liệu, một đoạn mã mới có chứa các thay đổi cần thiết sẽ được thêm vào trong kho lưu trữ này. Để thực hiện việc chuyển đổi cho cơ sở dữ liệu, các đoạn mã này sẽ được thực hiện theo đúng thứ tự mà chúng đã được tạo ra. Thư viện Flask-Migrate có các lệnh riêng được gọi thông qua lệnh
Lưu ý rằng lệnh flask cần có biến môi trường FLASK_APP để biết vị trí của ứng dụng Flask. Vì vậy, xin nhắc lại để chạy ứng dụng, chúng ta cần thiết lập biến môi trường Sau khi chạy lệnh này, bạn sẽ thấy thư mục mới tên là migrations có chứa một số file và một thư mục con của thư mục này tên là versions. Tất cả những file này là một phần trong mã nguồn của bạn và cần được thêm vào hệ thống quản lý mã nguồn của bạn. Chuyển đổi dữ liệu lần đầuKhi đã có kho lưu trữ cho chuyển đổi dữ liệu, chúng ta có thể tiến hành thực hiện việc chuyển đổi dữ liệu lần thứ nhất. Quá trình này sẽ tạo ra bảng user trong hệ thống cơ sở dữ liệu tương ứng với mô hình dữ liệu
Các dòng trạng thái của lệnh này cho chúng ta biết đại thể Alembic làm việc như thế nào trong quá trình này. Hai dòng đầu tiên chỉ mang tính tham khảo và có thể bỏ qua. Sau đó, Alembic cho biết đã tìm được một bảng user với hai chỉ mục. Tiếp theo, chúng ta cũng thấy được vị trí của mã kịch bản chuyển đổi. Chuỗi fcf566b5be7f là một chuỗi được sinh ra tự động và có giá trị duy nhất (nó sẽ có giá trị khác trên máy của bạn) cho quá trình chuyển đổi. Tham số Mã kịch bản cho chuyển đổi dữ liệu sinh ra sau lệnh này sẽ là một phần trong dự án của bạn và cần được thêm vào hệ thống quản lý mã nguồn mà bạn đang sử dụng. Nếu bạn muốn, bạn có thể xem thử các đoạn mã này. Bạn sẽ thấy rằng nó có hai hàm gọi là Lệnh
Vì ứng dụng của chúng ta sử dụng cơ sở dữ liệu SQLite, khi lệnh Cũng xin lưu ý rằng theo
mặc định, Flask-SQLAlchemy sử dụng quy ước đặt tên theo kiểu con rắn (snake-case) cho các bảng trong cơ sở dữ liệu. Vì vậy, nó sẽ tạo ra bảng Quá trình nâng cấp và giảm cấp cơ sở dữ liệuTại thời điểm này, ứng dụng của chúng ta vẫn còn rất sơ khai. Dù vậy, chúng ta cũng nên nói về cách thức chúng ta sẽ dùng cho việc chuyển đổi dữ liệu sau này. Giả sử chúng ta có hai phiên bản của ứng dụng: một trên máy của bạn dùng để phát triển, và một sẽ được dùng để triển khai vào máy chủ chính thức trên mạng mà mọi người có thể sử dụng. Bây giờ chúng ta sẽ thử xem xét tình huống sau: trong lần phát hành tiếp theo của ứng dụng, bạn đã thay đổi mô hình dữ liệu của bạn – ví dụ như chúng ta sẽ thêm một bảng mới vào cơ sở dữ liệu. Nếu không có quá trình chuyển đổi bạn sẽ cần phải tìm hiểu làm thế nào để thay đổi cấu trúc của cơ sở dữ liệu của bạn trong cả hai môi trường: môi trường phát triển và máy chủ. Và chúng ta sẽ phải tốn rất nhiều công sức cho việc này. Nhưng với sự hỗ trợ của chuyển đổi dữ liệu, sau khi bạn đã cập nhật mô hình dữ liệu, bạn sẽ tạo ra một mã kịch bản mới (với lệnh Khi bạn đã sẵn sàng để phát hành phiên bản tiếp theo của ứng dụng trên môi trường production, bạn chỉ cần lấy mã đã được cập nhật từ hệ thống quản lý mã nguồn. Mã này sẽ bao gồm cả mã kịch bản cho chuyển đổi dữ liệu. Và công việc tiếp theo của bạn chỉ đơn giản là chạy lệnh Như chúng ta đã thấy, Flask-Migration cũng bao gồm lệnh Sơ lược về quan hệ trong cơ sở dữ liệuCác hệ thống cơ sở dữ liệu quan hệ đảm nhiệm rất tốt việc lưu trữ và thiết lập các mối quan hệ giữa các bản ghi (record). Ví dụ như trong trường hợp một người sử dụng viết một bài trên blog, người sử dụng sẽ được đại diện bởi một bản ghi trong bản (table) Sau khi mối quan hệ giữa người sử dụng và bài viết được thiết lập, hệ thống cơ sở dữ liệu sẽ có thể tìm ra kết quả cho các truy vấn (query) về mối liên hệ này. Một ví dụ dễ thấy là bạn có một bài viết và muốn tìm ra ai đã viết bài này. Ngược lại, nếu bạn muốn tìm ra các bài viết được thực hiện bởi một tác giả, bạn sẽ phải dùng một truy vấn phức tạp hơn. Flask-SQLAlchemy sẽ hỗ trợ cho chúng ta trong cả hai trường hợp. Bây giờ hãy mở rộng cơ sở dữ liệu của chúng ta để lưu trữ cả các bài viết để hiểu rõ hơn về các quan hệ. Sau đây là cấu trúc của bảng Bảng Chúng ta sẽ cập nhật file app/models.py để tạo mô hình dữ liệu cho các bài viết như sau: app/models.py: Bảng Posts và liên hệ với bảng User
Lớp Trường Lớp Vì chúng ta vừa thay đổi mô hình dữ liệu, chúng ta cần tạo ra mã chuyển đổi mới:
Và tiếp theo, chúng ta cần tiến hành quá trình chuyển đổi bằng cách chạy các mã vừa sinh ra ở trên:
Đừng quên thêm các mã chuyển đổi mới này vào hệ thống quản lý mã nguồn của bạn nhé. Thực hànhSuốt từ đầu đến giờ, chúng ta hầu như chỉ nói về việc định nghĩa dữ liệu, thật là chán phải không? Bây giờ chúng ta hãy thực tập một chút để làm quen với cách hoạt động của cơ sở dữ liệu và Python. Bạn hãy gọi trình biên dịch Python bằng lệnh Tại dấu nhắc lệnh của trình biên dịch Python, hãy tham chiếu (import) đến các thư viện và đối tượng trong mô hình dữ liệu của chúng ta:
Hãy thử tạo một người sử dụng mới:
Ở đây chúng ta thấy có một khái niệm mới là session (phiên làm việc) khi chúng ta sử dụng các hàm trong Tiếp theo, chúng ta hãy thêm một người sử dụng nữa:
Đến đây, cơ sở dữ liệu của chúng ta có thể trả lời cho truy vấn tìm kiếm tất cả người sử dụng trong hệ thống:
Tât cả các đối tượng mô hình dữ liệu đều có thuộc tính Sau đây chúng ta sẽ thử tìm thông tin về người sử dụng qua Id của họ:
Vậy nếu chúng ta muốn thêm một bài viết thì sao?
Chúng ta không gán giá trị cho trường Để kết thúc mục này, chúng ta sẽ xem qua vài ví dụ truy vấn dữ liệu nữa:
Nếu bạn muốn tìm hiểu thêm về các ùy chọn khi truy vấn dữ liệu, bạn có thể tham khảo các tài liệu trực tuyến của Flask-SQLAlchemy. Và cuối cùng, chúng ta hãy thử xóa dữ liệu về người sử dụng và bài viết mà chúng ta đã tạo ra để dọn trống cơ sở dữ liệu cho phần tiếp theo:
Ngữ cảnh lệnhBạn có nhớ chúng ta đã làm gì ở đầu bài học trước không? Chúng ta đã gọi trình biên dịch Python và sau đó, thực hiện câu lệnh để tham chiếu (import) như sau:
Trong quá trình viết ứng dụng, bạn sẽ phải kiểm tra nhiều thứ qua chế độ dòng lệnh của Python (shell). Vì vậy, việc cứ phải lặp đi lặp lại lệnh import như trên sẽ rất mệt. Để giúp chúng ta, Flask cung cấp một lệnh rất hữu ích:
Trong một phiên làm việc bình thường, trình biên dịch Python không nhận ra Vì vậy, chúng ta sẽ giới thiệu thêm một hàm nữa trong myblog.py để tạo ra một ngữ cảnh lệnh để tự động tham chiếu đến tất cả các đối tượng cần thiết trong ứng dụng của chúng ta như cơ sở dữ liệu và mô hình dữ liệu như sau:
Decorator Sau khi đã tạo hàm xử lý ngữ cảnh lệnh như trên, bạn có thể làm sử dụng trực tiếp các đối tượng và hàm từ cơ sở dữ liệu mà không cần phải tham chiếu đến chúng:
Nếu bạn gặp lỗi Chúng ta sẽ kết thúc phần này ở đây. Hẹn gặp bạn trong phần tiếp theo. |