暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Flask 用户指南 - 教程(3)- 定义并访问数据库

数据库杂货铺 2022-02-17
1019

定义并访问数据库

 

该应用程序将使用 SQLite 数据库来存储用户和帖子。Python sqlite3 模块中内置了对 SQLite 的支持。

 

SQLite 很方便使用,因为它不需要设置单独的数据库服务器,并且内置于 Python 中。但是,如果并发请求试图同时向数据库写入数据,则每次写入都会按顺序进行,因此速度会减慢。小型应用程序不会在意这点。一旦程序变大了,可能就想要切换到另一个数据库。

 

本教程没有详细介绍 SQL。如果你不熟悉,请参阅 SQLite 官方文档。

 

连接到数据库

 

使用 SQLite 数据库(以及大多数其他 Python 数据库)时要做的第一件事是创建到它的连接。任何查询和操作都通过连接执行,该连接在工作完成后关闭。

 

web 应用程序中,这种连接通常与请求相关联。它在处理请求时的某个时间点创建,并在发送响应之前关闭。

 

# flaskr/db.py
import sqlite3


import click
from flask import current_app, g
from flask.cli import with_appcontext


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 是一个特殊的对象,对于每个请求都是唯一的。它用于存储请求期间多个函数可能访问的数据。该连接会被存储,如果在同一请求中第二次调用 get_db,则会重用连接,而不是创建新连接。

 

current_app 是另一个特殊对象,指向处理请求的 Flask 应用程序。由于使用了应用程序工厂,所以在编写其余代码时没有应用程序对象。get_db 将在创建应用程序并处理请求时调用,因此可以使用 current_app

 

sqlite3.connect() DATABASE 配置键指向的文件建立连接。这个文件此时还不存在,直到稍后初始化数据库。

 

sqlite3.Row 告诉连接返回行数据,类似于使用字典,可以按名称访问列。

 

close_db 通过 g.db 来检查是否创建了连接。如果连接存在,它将关闭。接下来,在应用程序工厂中引入 close_db 函数,以便在每次请求后调用它。

 

创建表

 

SQLite 中,数据存储在表和列中。在存储和检索数据之前,需要先创建这些表和列。Flaskr 将用户存储在 user 表中,并将帖子存储在 post 表中。创建一个带有 SQL 命令的文件,这些命令用于创建空表:

 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)
);

 

db.py 文件添加 Python 函数,运行这些 SQL 命令:

 

# 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')
@with_appcontext
def init_db_command():
"""Clear the existing data and create new tables."""
init_db()
click.echo('Initialized the database.')

 

open_resource() 打开一个文件,文件路径相对于 flaskr 软件包,这很有用,因为在以后部署应用程序时,不一定知道该位置在哪里。get_db 返回一个数据库连接,用于执行从文件读取的命令。

 

click.command() 定义一个名为 init-db 的命令行命令,该命令调用 init_db 函数,并向用户显示一条成功消息。

 

注册应用程序

 

close_db init_db_command 函数需要在应用程序实例中注册;否则,应用程序将不会使用它们。但是,由于使用的是工厂函数,因此在编写函数时该实例不可用。可以编写一个函数来接受应用程序并进行注册。

 

# flaskr/db.py
def init_app(app):
app.teardown_appcontext(close_db)
app.cli.add_command(init_db_command)

 

app.teardown_appcontext() 告诉 Flask 在返回响应后进行清理时调用该函数。

 

app.cli.add_command() 添加一个可以用 flask 命令调用的新命令。

 

从工厂导入并调用此函数。将新代码放在出厂函数的末尾,在返回应用程序之前。

 

# flaskr/__init__.py
def create_app():
app = ...
# existing code omitted


from . import db
db.init_app(app)


return app

 

初始化数据库文件

 

现在 init-db 已经在应用程序中注册,可以使用 flask 命令调用它,类似于之前的 run 命令。

 

运行 init-db 命令:

 

>flask init-db

 

现在项目中 instance 文件夹中将有一个 flaskr.sqlite 文件。

 

 


原文:

https://flask.palletsprojects.com/en/2.0.x/tutorial/database/



文章转载自数据库杂货铺,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论