Chỉ định và truy cập cơ sơ dữ liệu
Ứng dụng sẽ sử dụng cơ sở dữ liệu SQLite để lưu thông tin users
và posts
. Python có hỗ trợ tích hợp cho SQLite trong module sqlite3
SQLite thuận tiện vì không cần phải thiết lập 1 máy chủ cơ sở dữ liệu riêng biệt và nó được tích hợp sẵn trong Python. Tuy nhiên, nếu yêu cầu đồng thời truy vấn đến cơ sở dữ liêu cùng một thời điểm, nó sẽ chậm lại vì các yêu cầu sẽ thực hiện tuần tự. Đối với dự án nhỏ thì bạn không nhận thấy điều đó. Đến khi dự án của bạn lớn lên, có thể bạn sẽ chuyển đổi sang cơ sở dữ liệu khác.
Trong phần hướng dẫn này thì không đi sâu về SQL, nếu bạn muốn hiểu rõ về nó hơn, thì bạn có thể xem tài liệu của SQLite
Kết nối đến cơ sở dữ liệu
Điều đầu tiên cần làm khi làm việc với SQLite database (Và các thư viện cơ cở dữ liệu của Python khác) thì cần tạo một connection (kết nối) đến nó. Mỗi truy vấn và thao tác thì được thực hiện bằng cách sử dụng kết nối. Kết nối sẽ được đóng lại sau khi công việc kết thúc
Trong ứng dụng web thì kết nối này được gắn với yêu cầu. Nó thì được tạo tại một vài điểm khi xử lý yêu cầu và được đóng trước khi kết quả response được trả về.
flaskr/db.py
import sqlite3 import click
from flask import current_app, g def get_db(): if 'db' not in g: g.db = sqlite3.connect( current_app.config['DATABASE'], detect_types=sqlite3.PARSE_DECLTYPES ) g.db.row_factory = sqlite3.Row return g.db def close_db(e=None): db = g.pop('db', None) if db is not None: db.close()
-
g
là đối tượng đặc biệt cho mỗi yêu cầu. Nó thì được sử dụng để lưu trữ dữ liệu. Có thể truy cập bởi nhiều chức năng khi yêu cầu. Kết nối thì được lưu trữ và sử dụng lại thay vì tạo mới một kết nối nếuget_db
được gọi lần thứ 2 trong cùng một yêu cầu -
current_app
là một đối tượng đặc biệt khác trỏ đến ứng dụng Flask đang xử lý yêu cầu. Vì bạn đã sử dụng application factory nên không có đối tượng ứng dụng nào khi viết phần còn lại của code.get_db
sẽ được gọi khi ứng dụng đã được tạo và đang xử lý một yêu cầu, vì vậycurrent_app
có thể sử dụng được. -
sqlite3.connect()
thiết lập kết nối đến file được chỉ định bởiDATABASE
khóa cấu hình. File này chưa nhất thiết phải tồn tại và sẽ tồn tại cho đến khi bạn khởi tạo cơ sở dữ liệu sau này. -
sqlite3.Row
yêu cầu kết nối trả về các hàng hoạt động giống như ký tự. Điều này cho phép truy cập các cột theo tên. -
close_db
kiểm tra xem kết nối có được tạo hay không bằng cách kiểm tra xemg.db
đã được đặt chưa. Nếu kết nối tồn tại, nó sẽ bị đóng. Tiếp theo, bạn sẽ cho ứng dụng của mình biết vềclose_db
chức năng trong nhà máy ứng dụng để nó được gọi sau mỗi yêu cầu.
Tạo table
Trong SQLite, dữ liệu được lưu trữ trong table và colunm . Chúng cần được tạo trước khi bạn có thể lưu trữ và truy xuất dữ liệu. Flaskr sẽ lưu trữ người dùng trong bảng user
và các bài đăng trong bảng post
. Tạo một file có các lệnh SQL cần thiết để tạo các bảng trống:
flaskr/schema.sql
DROP TABLE IF EXISTS user;
DROP TABLE IF EXISTS post; CREATE TABLE user ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT UNIQUE NOT NULL, password TEXT NOT NULL
); CREATE TABLE post ( id INTEGER PRIMARY KEY AUTOINCREMENT, author_id INTEGER NOT NULL, created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, title TEXT NOT NULL, body TEXT NOT NULL, FOREIGN KEY (author_id) REFERENCES user (id)
);
Thêm các hàm Python sẽ chạy các lệnh SQL này vào file db.py
flaskr/db.py
def init_db(): db = get_db() with current_app.open_resource('schema.sql') as f: db.executescript(f.read().decode('utf8')) @click.command('init-db')
def init_db_command(): """Clear the existing data and create new tables.""" init_db() click.echo('Initialized the database.')
-
open_resource()
mở một file liên quan đến packageflaskr
, điều này rất hữu ích vì sau này bạn không nhất thiết phải biết vị trí đó ở đâu khi triển khai ứng dụng.get_db
trả về một kết nối cơ sở dữ liệu, được sử dụng để thực thi các lệnh đọc từ file. -
click.command()
xác định một lệnh dòng lệnhinit-db
gọi hàminit_db
và hiển thị thông báo thành công cho người dùng.
Đăng ký với ứng dụng
Các hàm close_db
và init_db_command
cần phải được đăng ký với phiên bản ứng dụng; nếu không, chúng sẽ không được ứng dụng sử dụng. Tuy nhiên, vì bạn đang sử dụng function factory nên phiên bản đó không có sẵn khi viết hàm. Thay vào đó, hãy viết một hàm nhận một ứng dụng và thực hiện đăng ký.
flaskr/db.py
def init_app(app): app.teardown_appcontext(close_db) app.cli.add_command(init_db_command)