请优先查看(一)(二).
网站的基本通讯是从客户端/web到服务端/flask,然后根据需求操作数据库,当然,这是最基本,还可以增加Nginx,uwxgi来实现反向代理,负载均衡等其他功能,不过这里不涉及这些,这里的目的是:先让你的flask网站跑起来.
那么如何连接数据库呢?
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
函数,这样每次请求后就会 调用它。
更详细的可以查阅官方文档.
建表文件
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)
);
在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:
print( current_app.config['DATABASE'])
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()
####新增代码
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.')
#注册到应用工厂
def init_app(app):
app.teardown_appcontext(close_db)
app.cli.add_command(init_db_command)
open_resource() 打开一个文件,该文件名是 相对于 flaskr
包的。这样就不需要考虑以后应用具体部署在哪个位置。 get_db
返回一个数据库连接,用于执行文件中的命令。
click.command() 定义一个名为 init-db
命令行,它调用 init_db
函数,并为用户显示一个成功的消息。
app.teardown_appcontext() 告诉 Flask 在返回响应后进行清理的时候调用此函数。
app.cli.add_command() 添加一个新的 可以与 flask
一起工作的命令。
这里展示vscode新建终端
flaskr/__init__.py调用初始化
##########之前已码代码
import os
from flask import Flask
from flaskr.setting import SECRET_KEY
def create_app(test_config=None):
# create and configure the app
app = Flask(__name__, instance_relative_config=True)
app.config.from_mapping(
#是被 Flask 和扩展用于保证数据安全的。在开发 过程中,为了方便可以设置为 'dev' ,但是在发布的时候应当使用 一个随机值来重载它。
SECRET_KEY='!@#$%^&iewjqda(*^',
DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'),
)
if test_config is None:
# Load the instance config, if it exists, when not testing
app.config.from_pyfile('config.py', silent=True)
else:
# Load the test config if passed in
app.config.from_mapping(test_config)
# ensure the instance floder exists
try:
os.makedirs(app.instance_path)
except OSError:
pass
# a simple page that says hello
@app.route('/hello')
def hello():
return 'Hello, World!'
############新增代码
#数据库对象
from . import db
db.init_app(app)
return app
(需要先停止之前跑起来的hello world)运行:
现在会有一个 flaskr.sqlite
文件出现在项目所在文件夹的 instance
文件夹中。
安装mysql:
我在本站找到个挺不错的教程,并尝试按照其步骤成功安装,这里给出地址,或者各位自行查找:Ubuntu16.04上安装MySQL(详细过程)_Runningluffy的博客-CSDN博客
下文: