Python Flask框架-开发简单博客-定义和操作数据库
创始人
2024-04-04 16:36:50

作者:Eason_LYC
悲观者预言失败,十言九中。 乐观者创造奇迹,一次即可。
一个人的价值,只在于他所拥有的。所以可以不学无术,但不能一无所有!
技术领域:WEB安全、网络攻防
关注WEB安全、网络攻防。我的专栏文章知识点全面细致,逻辑清晰、结合实战,让你在学习路上事半功倍,少走弯路!
个人社区:极乐世界-技术至上
追求技术至上,这是我们理想中的极乐世界~(关注我即可加入社区)

本专栏是对Flask官方文档中个人博客搭建进行的归纳总结,与官方文档结合事半功倍。基础薄弱的同学请戳Flask官方文档教程

本人经验,学习一门语言或框架时,请首先阅读官方文档。学习完毕后,再看其他相关文章(如本系列文章),才是正确的学习道路。

如果python都完全不熟悉,一定不要着急学习框架,请首先学习python官方文档,一步一个脚印。要不然从入门到放弃是大概率事件。
Python 官方文档教程

本系列已发布文章:

  1. Python Flask框架-开发简单博客-开篇介绍
  2. Python Flask框架-开发简单博客-项目布局、应用设置

文章目录

  • 1. 本章知识点总结
  • 2. 定义(创建)数据库
    • 2.1 简单规划
    • 2.2 user表字段分析
    • 2.3 post表字段分析
    • 2.4 创建数据库的sql脚本
  • 3. 操作数据库
  • 4. 初始化数据库文件并测试

1. 本章知识点总结

请添加图片描述

2. 定义(创建)数据库

2.1 简单规划

开发的个人博客,计划使用SQLite 数据库来储存用户和博客内容。 Python 内置了 SQLite 数据库支持,相应的模块为 sqlite3
如果你不是很熟悉 SQL ,请先阅读SQLite 官方文档 ,不用精通,能使用即可。

计划建两个表分别为user表和post表,sql表文件保存路径为flaskr/schema.sql

2.2 user表字段分析

  • id:用户id、整数、主键、自增加
  • username:用户名、文本、值唯一,不能重复
  • password: 登陆密码、文本、不能为空

flaskr/schema.sql

2.3 post表字段分析

  • id: 文章id、整数、主键、自增加
  • author_id:文章作者id、整数、不为空、外键
  • created:文章创建时间、时间戳、不为空(默认值为创建时间)
  • title:文章标题、文本、不为空
  • body:文章内容、文本,不为空

2.4 创建数据库的sql脚本

编写schema.sql的脚本,该脚本用于创建SQLite 数据库,并内置user表和post表。所以这个创建过程仅在个人博客第一次运行时运行一次即可。
后续数据库内容的更新应执行常规的增删改查操作。

注意,该脚本仅在个人博客第一次运行时创建数据库,后续不应再次运行(否则,数据库将被重置)。
所以在第一次运行时,要先卸载数据库中所有表,以防报错。

路径flaskr/schema.sql

// 卸载库中所有表
DROP TABLE IF EXISTS user;
DROP TABLE IF EXISTS post;// 新建user表
CREATE TABLE user (id INTEGER PRIMARY KEY AUTOINCREMENT,username TEXT UNIQUE NOT NULL,password TEXT NOT NULL
);// 新建post表
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)
);

3. 操作数据库

前面写完了sql脚本,接下来就要写db.py这个python脚本,用来操作数据库。路径规划为flaskr/db.py
操作具体包括了如下几个具体功能

  • 建立数据库连接 — 用于将程序与数据库建立连接
  • 关闭数据库连接 — 完成一次操作后,及时关闭当前连接
  • 初始化数据库 — 第一次运行博客时创建数据库生成表
  • 在应用中注册db.py实现flask的调用
    这个理解起来,有点绕,简单说来,
    我们自己定义的函数需要在应用实例中注册,否则无法使用。应用实例就是app = Flask(__name__, instance_relative_config=True)但是问题是,这个app=我们是写在了工厂函数中(create_app)。意思就是这个实例其实并没有建立,所以我们这个注册只能在工厂函数中注册。那问题来了,在一个工厂函数中如何注册。
    答案就是,函数调用另一个函数实现:工厂函数中app实例动态创建时,动态调用注册函数,实现动态注册。

flaskr/db.py 请注意代码中的注释和下面关于各函数的说明文字。

import sqlite3
import click
from flask import current_app, g
from flask.cli import with_appcontext# 1.创建数据库连接
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.Rowreturn g.db# 2. 关闭数据库连接
def close_db():db = g.pop('db', None)if db is not None:db.close()# 3. 初始化数据库
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
# app context,应用上下文,存储的是应用级别的信息,比如数据库连接信息。
# request context,程序上下文,存储的是请求级别的信息,比如当前访问的url
def init_db_command():init_db()click.echo('数据库初始化成功。')# 4. 在应用中注册`db.py`实现flask的调用
# 此处为注册函数,另一端在工厂函数(create_app)中,动态调用此函数,实现动态注册。
def init_app(app):# teardown_appcontext# 不管是否有异常,注册的函数都会在每次请求之后执行。# flask 为上下文提供了一个 teardown_appcontext 钩子,使用它注册的毁掉函数会在程序上下文被销毁时调用,通常也在请求上下文被销毁时调用。# 比如你需要在每个请求处理结束后销毁数据库连接:app.teardown_appcontext 装饰器注册的回调函数需要接收异常对象作为参数,当请求被正常处理时这个参数将是None,这个函数的返回值将被忽略。# 参考链接 https://www.cnblogs.com/Wu13241454771/p/15439350.htmlapp.teardown_appcontext(close_db)app.cli.add_command(init_db_command)
  1. g 是一个特殊对象,独立于每一个请求。在处理请求过程中,它可以用于储存可能多个函数都会用到的数据。把连接储存于其中,可以多次使用,而不用在同一个请求中每次调用 get_db 时都创建一个新的连接。
  2. current_app 是另一个特殊对象,该对象指向处理请求的 Flask 应用。这里使用了应用工厂,那么在其余的代码中就不会出现应用对象。当应用创建后,在处理一个请求时, get_db 会被调用。这样就需要使用 current_app 。
  3. sqlite3.connect() 建立一个数据库连接,该连接指向配置中的 DATABASE 指定的文件。这个文件现在还没有建立,后面会在初始化数据库的时候建立该文件。
  4. sqlite3.Row 告诉连接返回类似于字典的行,这样可以通过列名称来操作数据。
  5. close_db 通过检查 g.db 来确定连接是否已经建立。如果连接已建立,那么就关闭连接。以后会在应用工厂中告诉应用 close_db 函数,这样每次请求后就会调用它。
  6. open_resource() 打开一个文件,该文件名是相对于 flaskr 包的。这样就不需要考虑以后应用具体部署在哪个位置。 get_db 返回一个数据库连接,用于执行文件中的命令。
  7. click.command() 定义一个名为 init-db 命令行,它调用 init_db 函数,并为用户显示一个成功的消息。
  8. app.teardown_appcontext() 告诉 Flask 在返回响应后进行清理的时候调用此函数。
  9. app.cli.add_command() 添加一个新的可以与 flask 一起工作的命令。

flaskr/__init__.py

def create_app():app = ...# 之前文章中已经写的代码# 本次新增如下两行代码from flaskr import dbdb.init_app(app)# 之前文章中已经写的代码return app

4. 初始化数据库文件并测试

参考上次文章如何配置flask相关环境 Python Flask框架-开发简单博客-项目布局、应用设置

在cmd模式下,执行flask init-db
请添加图片描述成功后,在pycharm中就可以直接看到生成的数据库和其中的user表和post表了
请添加图片描述

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...