Flask:操作SQLite3(0.1)
Windows 10家庭中文版,Python 3.6.4,Flask 1.0.2
本文介绍了第一次在Flask框架中操作SQLite3数据库的测试,参考了官网的文档Using SQLite 3 with Flask,直接使用了里面定义
的几个函数:init_db、get_db、close_connection、make_dicts,另外,自己编写了视图(View)函数实现添加、读取操作。
本测试项目的目标
-使用建模文件初始化数据库成功
-连接数据库成功
-关闭数据库成功
-添加数据成功
-读取数据成功,并成功返回到页面
测试步骤
1.建立空的SQLite3数据库文件 和 数据库建模文件
前面一篇关于SQLite3的文章有介绍,使用sqlite3.exe即可;
数据库建模文件,参考SQLite官方文档SQL As Understood By SQLite建立;
下面是我的建模文件内容:
DROP TABLE IF EXISTS post;
CREATE TABLE post (
id INTEGER PRIMARY KEY AUTOINCREMENT,
body VARCHAR(500) NOT NULL,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
如果原数据库存在,就删除,然后建立新的。
数据表post,包括id、body、created三个字段,其中,body字段为提交的消息,created为消息存放到数据库的时间。
建立好的数据库文件和建模文件放到项目的db文件夹下:
说明,数据库文件和建模文件不一定要放到db文件夹下,也可以放到Flask项目的根目录下(Q:是否可以放到项目之外呢?不建议。),只要程序中把相关路径输入正确即可。
2.编写Flask项目文件main.py(单模块项目)
将文档Using SQLite 3 with Flask中的一些代码拷贝到many.py中。
from flask import * # 导入flask模块下的所有元素
import sqlite3 # 导入sqlite3模块 app = Flask('Posts') # 建立Flask应用 DATABASE = 'db/posts.db' # 数据库文件地址
DATABASE_INIT_FILE = 'db/init.sql' # 数据库建模文件地址 # init_db()
def init_db(): # 此函数要使用 数据库建模文件 初始化数据库:建立post表(Initial Schemas)。此函数在命令行中使用,仅一次,再次使用会删除数据库中已有数据。
with app.app_context(): # 官网文档说了原因:不是在Web应用中使用,而是在Python Shell中使用时需要此语句(Connect on Demand)。
db = get_db()
with app.open_resource(DATABASE_INIT_FILE, mode='r') as f: # with语句用法!
db.cursor().executescript(f.read()) # 执行建模文件中的脚本
db.commit() # 提交事务 # make_dicts()
def make_dicts(cursor, row): # 将查询返回的数据的转换为字典类型,这样会跟方便使用。此函数会在get_db()函数中用到,赋值给db.row_factory。
return dict((cursor.description[idx][0], value)
for idx,value in enumerate(row)) # get_db()
def get_db(): # 获取数据库连接
db = getattr(g, '_database', None) # g对象时一个Flask应用的公共对象(和request、session一样),用于存储用户的数据——整个应用共享!
if db is None:
db = g._database = sqlite3.connect(DATABASE) # 建立数据库连接
db.row_factory = make_dicts # 转换默认的查询数据类型为字典类型,也可以使用sqlite3.Row
return db # 返回数据库连接,可能返回为None # close_connection()
@app.teardown_appcontext # 这个装饰器用于实现在请求的最后自动关闭数据库连接的功能
def close_connection(exception): # 关闭数据库连接
db = getattr(g, '_database', None)
if db is not None:
db.close()
说明,在誊写代码过程中,把cursor.description写错了,直到最后运行程序才发现了错误。
以上,初始化数据库——只执行一次、获取数据库连接、关闭数据库连接的程序都有了。接下来,建立一个视图函数测试数据库连接、关闭数据库连接是否正常执行。
注意,在此时之前需要再get_db、close_connection函数中添加调试语句,print或者app.logger都可以。
@app.route('/testdb')
def testdb():
get_db()
return "After test"
然后,启动Flask项目,使用浏览器访问/testdb,检查项目命令行即可看到添加的调试语句——提示错误就继续修改。
3.使用 建模文件 初始化 数据库文件
这个时候需要用到上面的init_db()函数了。
在文档Using SQLite 3 with Flask的Initial Schemas中有介绍,将Flask项目模块的init_db()函数导入,再执行即可。
下面是我的测试情况:成功 按照建模文件 建立 数据表post
注意,在Python Shell执行上面的命令时,需要保证当前目录为Flask项目所在目录。
4.建立测试项目需要视图函数(View functions)
本测试项目需要实现发布消息、展示消息的功能(但并没有做到同一个页面上),因此,建立了三个视图函数来实现目标:
4.1 home()
首页,返回一个模板用于添加post。
此模板文件仅包含静态内容,因此,render_template只有一个参数。
# path: /
# show posts
@app.route('/')
def home():
return render_template('temp.html')
模板文件主要内容:定义表单,action为“pureadd”
<form action="pureadd" method="post">
<textarea name="newpost" style="width:200px;height:100px;" maxlength="500"></textarea><br />
<input type="submit" value="添加" />
</form>
<a href="/pureshow">展示帖子</a><br />
页面如下:
4.2 pureadd()
一个单纯地(pure)用于添加一条post到数据库的视图函数,会对参数进行校验、发生错误时会返回错误的信息等。
仅支持POST方法的请求。
此视图的返回信息中还包括跳转到添加页面、展示页面的链接。
# pure add page for test
@app.route('/pureadd', methods=['POST'])
def pureadd():
# step 1. get the new post and check the data
newp = ''
try:
newp = request.form['newpost']
except:
return 'ERROR: Invalid form parameters!' print('newp = "', newp, '"') newp2 = newp.strip() # 清理post两遍的空格,然后赋值给新变量——此时旧变量没有改变 if newp2 == '':
return 'Warning: New post is empty!<br/>' \
'<a href="/">继续添加</a><br/>' \
'<a href="/pureshow">展示帖子</a><br />' # step 2.write the new post into database
sqlmode = 'INSERT INTO post(body) VALUES(?)' # 添加数据的SQL语句,占位符使用问号(?)。需要注意的是,如果是MySQL,占位符是百分号(%)。
try:
db = get_db()
cursor = db.cursor()
cursor.execute(sqlmode, (newp2,))
cursor.close() # 关闭cursor。Q:是否一定要关闭呢?不关闭有什么影响?
db.commit() # 需要commit,否则,数据不会更新到数据库
except Exception as e:
return '<span style="color:red;">INFO: New post added failed <br/> %s</span><br/>' \
'<a href="/">继续添加</a><br/>' \
'<a href="/pureshow">展示帖子</a><br />' % str(e)
else:
return 'INFO: New post added <br/><pre>[%s]</pre><br/>' \
'<a href="/">继续添加</a><br/>' \
'<a href="/pureshow">展示帖子</a><br />' % newp
成功添加一条数据:
数据库中显示添加的数据:
4.3 pureshow()
此视图函数用于 展示数据库中的数据。
将查询到的数据直接返回到 模板文件showall.html 中。
注意,需要提一下前面get_db()函数中的设置db.row_factory为make_dicts。如果没有这个赋值的话,模板文件的解析数据方式将会改变。
# pure show page for test
@app.route('/pureshow')
def pureshow():
sqlmode = "SELECT * FROM post ORDER BY created DESC"
rv = []
try:
db = get_db()
cursor = db.execute(sqlmode)
rv = cursor.fetchall()
cursor.close()
except Exception as e:
print(e)
abort(500)
else:
return render_template('showall.html', posts=rv)
模板文件showall.html的主要内容:使用for循环将pureshow()函数返回的内容展示出来
<div id="postslist">
{% for post in posts %}
<div class="post_item" id="post{{ post.id }}">
{{ post.body }}<br/>
{{ post.created }}
</div>
{% endfor %}
</div>
<a href="/">继续添加</a>
/pureshow页面展示内容如下:
注意,数据库中保存的时间为UTC时间,在实际应用中,展示出来时还需要添加对应的时差。
参考链接
后续
上面的方法很简单,在Flask提供的扩展中,有一个叫做SQLAlchemy的,使用它可以更高效地操作各种数据库,所以,下一步就是学习并使用它了。
官方文档SQLAlchemy in Flask中有介绍,看过一遍了,现在,该实践了。
前面做的项目都是基于单个的模型文件的,后面需要升级:基于package的方式、使用Blueprint,这两个是重点啊!
在官网的Tutorial会有关于SQLAlchemy、Blueprint的介绍,也是需要参考的。
Flask,还需要以周计的时间才能熟练使用啊。
自己没有做过完整的Web应用,在URL设计等方面存在一些挑战,因此,这个测试项目才会如此simple。
本来还想实现用户登录、退出等“稍微复杂”的功能的——最初的想法,最后都只能放弃了。
我想,在熟悉了SQLAlchemy、Blueprint后,Web开发的功力会有很大提高的。
对了,还有就是 怎么提供数据接口给前端,比如RESTful API等,都是需要熟练的。
Flask:操作SQLite3(0.1)的更多相关文章
- flask, SQLAlchemy, sqlite3 实现 RESTful API 的 todo list, 同时支持form操作
flask, SQLAlchemy, sqlite3 实现 RESTful API, 同时支持form操作. 前端与后台的交互都采用json数据格式,原生javascript实现的ajax.其技术要点 ...
- iOS 数据库sqlite3.0操作--超简单--看我就够啦
iOS客户端数据存储的方式有很多,下面主要是介绍苹果自带的sqlite3.0的使用方法. 首先导入sqlite3.0的框架.然后导入头文件#import <sqlite3.h>就行了 下面 ...
- IOS数据库操作SQLite3使用详解(转)
iPhone中支持通过sqlite3来访问iPhone本地的数据库.具体使用方法如下1:添加开发包libsqlite3.0.dylib首先是设置项目文件,在项目中添加iPhone版的sqlite3的数 ...
- flask 操作mysql的两种方式-sql操作
flask 操作mysql的两种方式-sql操作 一.用常规的sql语句操作 # coding=utf-8 # model.py import MySQLdb def get_conn(): conn ...
- [py]flask操作cookie&django的seesion和cookie机制
浏览器同源策略(same-origin policy) csrf攻击防御核心点总结 django的cookie和session操作-7天免登录 flask操作cookie&django的see ...
- 【delphi】delphi操作sqlite3
SQLite SQLite是一个老牌的轻量级别的本地文件数据库,完全免费且开源,不需要安装,无须任何配置,当然,这样管理功能就不是很强大了,但是它的主要应用也是在本地数据库,可以说是最简单好用的嵌入式 ...
- Flask 中文手册 0.10 文档
Flask 中文手册 0.10 文档 欢迎使用 Flask 欢迎阅读 Flask 文档. 本文档分为几个部分.我推荐您先从 安装 开始,之后再浏览 快速入门 章节. 教程 比快速入门更详细地介绍了如何 ...
- litepal更好的操作sqlite3,配置与基本操作
litepal更好的操作sqlite3 配置 在app下的build.gradle中加入 创建litepal.xml配置 在app/src/main下面创建assets,新建litepal.xml & ...
- iOS: 学习笔记, 使用FMDatabase操作sqlite3
使用FMDatabase操作sqlite3数据库非常简单和方便 // // main.m // iOSDemo0602_sqlite3 // // Created by yao_yu on 14-6- ...
随机推荐
- uoj318 [NOI2017]蔬菜 【贪心 + 堆 + 并查集】
题目链接 uoj 题解 以前看别人博客,在考场上用费用流做,一直以为这题是毒瘤网络流题 没想到竟然是贪心模拟题... 如果只有一个蔬菜呢?这就是一个经典的普及难度的贪心,正着推面临优先选择的困难,而逆 ...
- 方程式EQGRP_Lost_in_Translation工具之fb.py
使用方法: 环境搭建:win2003下测试: 下载python2.6并安装 下载pywin32并安装 将C:\Python26添加到环境变量PATH中 将整个windows目录复制到windows20 ...
- HDU 5306 线段树
吉司机课件题. 区间min,区间最值,区间和. 如果用最大值和次大值能更新区间和那就更新打标记,否则暴力dfs. #include<iostream> #include<cstdio ...
- bug3 乱码问题
出现乱码问题是因为各软件之间的编码方式不同导致 1.tomcat修改编码方法: 2.myeclipse中修改编码方式的方法: window----preference ----general----- ...
- 主角场景Shader效果:描边
基本思路:Shader用两个Pass,一个渲染描边部分,一个渲染物体部分. Pass1:剔除正面,渲染背面,把顶点延法线方向外围扩展一定宽度,用来表现描边的粗细,这部分用自己设定的颜色. Pass2: ...
- vue相关安装命令
安装cnpm npm install cnpm -g --registry=https://registry.npm.taobao.org
- Spring @Transactional注解不回滚不起作用无效
原文地址:http://www.cnblogs.com/wuxiaofeng/p/6819209.html 这几天在项目里面发现我使用@Transactional之后,抛了异常居然不回滚.后来终于 ...
- ZeroMQ API(七) 安全
1.无安全性:zmq_null(7) 1.1 名称 zmq_null - 没有安全性或机密性 1.2 概要 NULL机制由ZMTP 3.0规范定义:http://rfc.zeromq.org/spec ...
- httpclient4.5 连接池的封装
随着微服务的流行,服务之间的http调用越来越多,遇到的问题也比较多,写这边文章的目的也是将自己遇到的坑和解决方案跟大家分享 一.为什么要用Http连接池 1.降低延迟:如果不采用连接池,每次连接发起 ...
- Configure文件学习
Linux安装软件有一种方式就是通过源码安装,源码通常是一个压缩包,打开压缩包,经常会看到一个叫configure的文件,而不见makefile文件.通常我们在自己的电脑写应用的时候都是通过makef ...