+1

#3 Kết nối cơ sở dữ liệu SQLite với Flask

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 usersposts. 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ếu get_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ậy current_app có thể sử dụng được.

  • sqlite3.connect() thiết lập kết nối đến file được chỉ định bởi DATABASE 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 xem g.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 package flaskr , đ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ệnh init-db gọi hàm init_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_dbinit_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)

All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.