热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Flask:操作SQLite3(0.1)

Windows10家庭中文版,Python3.6.4,Flask1.0.2本文介绍了第一次在Flask框架中操作SQLite3数据库的测试,参考了官网的文档UsingSQLite3

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建立;

下面是我的建模文件内容:

1 DROP TABLE IF EXISTS post;
2 CREATE TABLE post (
3     id INTEGER PRIMARY KEY AUTOINCREMENT,
4     body VARCHAR(500) NOT NULL,
5     created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
6 );

如果原数据库存在,就删除,然后建立新的。

数据表post,包括id、body、created三个字段,其中,body字段为提交的消息,created为消息存放到数据库的时间。

 

建立好的数据库文件和建模文件放到项目的db文件夹下:

 

说明,数据库文件和建模文件不一定要放到db文件夹下,也可以放到Flask项目的根目录下(Q:是否可以放到项目之外呢?不建议。),只要程序中把相关路径输入正确即可。

 

2.编写Flask项目文件main.py(单模块项目)

将文档Using SQLite 3 with Flask中的一些代码拷贝到many.py中。

 1 from flask import * # 导入flask模块下的所有元素
 2 import sqlite3 # 导入sqlite3模块
 3 
 4 app = Flask('Posts') # 建立Flask应用
 5 
 6 DATABASE = 'db/posts.db' # 数据库文件地址
 7 DATABASE_INIT_FILE = 'db/init.sql' # 数据库建模文件地址
 8 
 9 # init_db()
10 def init_db(): # 此函数要使用 数据库建模文件 初始化数据库:建立post表(Initial Schemas)。此函数在命令行中使用,仅一次,再次使用会删除数据库中已有数据11     with app.app_context(): # 官网文档说了原因:不是在Web应用中使用,而是在Python Shell中使用时需要此语句Connect on Demand)。
12         db = get_db()
13         with app.open_resource(DATABASE_INIT_FILE, mode='r') as f: # with语句用法!
14             db.cursor().executescript(f.read()) # 执行建模文件中的脚本
15         db.commit() # 提交事务
16 
17 # make_dicts()
18 def make_dicts(cursor, row): # 将查询返回的数据的转换为字典类型,这样会跟方便使用。此函数会在get_db()函数中用到,赋值给db.row_factory。
19     return dict((cursor.description[idx][0], value)
20                 for idx,value in enumerate(row))
21 
22 # get_db()
23 def get_db(): # 获取数据库连接
24     db = getattr(g, '_database', None) # g对象时一个Flask应用的公共对象(和request、session一样),用于存储用户的数据——整个应用共享!
25     if db is None:
26         db = g._database = sqlite3.connect(DATABASE) # 建立数据库连接
27         db.row_factory = make_dicts # 转换默认的查询数据类型为字典类型,也可以使用sqlite3.Row
28     return db # 返回数据库连接,可能返回为None
29 
30 # close_connection()
31 @app.teardown_appcontext # 这个装饰器用于实现在请求的最后自动关闭数据库连接的功能
32 def close_connection(exception): # 关闭数据库连接
33     db = getattr(g, '_database', None)
34     if db is not None:
35         db.close()

 

说明,在誊写代码过程中,把cursor.description写错了,直到最后运行程序才发现了错误。

 

以上,初始化数据库——只执行一次、获取数据库连接、关闭数据库连接的程序都有了。接下来,建立一个视图函数测试数据库连接、关闭数据库连接是否正常执行。

注意,在此时之前需要再get_db、close_connection函数中添加调试语句,print或者app.logger都可以。

1 @app.route('/testdb')
2 def testdb():
3     get_db()
4     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只有一个参数。

1 # path: /
2 # show posts
3 @app.route('/')
4 def home():
5     return render_template('temp.html')

模板文件主要内容:定义表单,action为“pureadd”

1 <form action="pureadd" method="post">
2     <textarea name="newpost" style="width:200px;height:100px;" maxlength="500">textarea><br />
3     <input type="submit" value="添加" /> 
4 form>
5 <a href="/pureshow">展示帖子a><br />

页面如下:

 

4.2 pureadd()

一个单纯地(pure)用于添加一条post到数据库的视图函数,会对参数进行校验、发生错误时会返回错误的信息等。

仅支持POST方法的请求。

此视图的返回信息中还包括跳转到添加页面、展示页面的链接。

 1 # pure add page for test
 2 @app.route('/pureadd', methods=['POST'])
 3 def pureadd():
 4     # step 1. get the new post and check the data
 5     newp = ''
 6     try:
 7         newp = request.form['newpost']
 8     except:
 9         return 'ERROR: Invalid form parameters!'
10     
11     print('newp = "', newp, '"')
12     
13     newp2 = newp.strip() # 清理post两遍的空格,然后赋值给新变量——此时旧变量没有改变
14     
15     if newp2 == '':
16         return 'Warning: New post is empty!
' \ 17 '继续添加
' \ 18 '展示帖子
' 19 20 # step 2.write the new post into database 21 sqlmode = 'INSERT INTO post(body) VALUES(?)' # 添加数据的SQL语句,占位符使用问号(?)。需要注意的是,如果是MySQL,占位符是百分号(%)。 22 try: 23 db = get_db() 24 cursor = db.cursor() 25 cursor.execute(sqlmode, (newp2,)) 26 cursor.close() # 关闭cursor。Q:是否一定要关闭呢?不关闭有什么影响? 27 db.commit() # 需要commit,否则,数据不会更新到数据库 28 except Exception as e: 29 return 'INFO: New post added failed
%s

' \ 30 '继续添加
' \ 31 '展示帖子
' % str(e) 32 else: 33 return 'INFO: New post added
[%s]

' \ 34 '继续添加
' \ 35 '展示帖子
' % newp

 

成功添加一条数据:

 

数据库中显示添加的数据:

 

4.3 pureshow()

此视图函数用于 展示数据库中的数据。

将查询到的数据直接返回到 模板文件showall.html 中。

注意,需要提一下前面get_db()函数中的设置db.row_factory为make_dicts。如果没有这个赋值的话,模板文件的解析数据方式将会改变。

 1 # pure show page for test
 2 @app.route('/pureshow')
 3 def pureshow():
 4     sqlmode = "SELECT * FROM post ORDER BY created DESC"
 5     rv = []
 6     try:
 7         db = get_db()
 8         cursor = db.execute(sqlmode)
 9         rv = cursor.fetchall()
10         cursor.close()
11     except Exception as e:
12         print(e)
13         abort(500)
14     else:
15         return render_template('showall.html', posts=rv)

模板文件showall.html的主要内容:使用for循环将pureshow()函数返回的内容展示出来

1 <div id="postslist">
2     {% for post in posts %}
3         <div class="post_item" id="post{{ post.id }}">
4             {{ post.body }}<br/>
5             {{ post.created }}
6         div>
7     {% endfor %}
8 div>
9 <a href="/">继续添加a>

/pureshow页面展示内容如下:

 

注意,数据库中保存的时间为UTC时间,在实际应用中,展示出来时还需要添加对应的时差。

 

参考链接

Using SQLite 3 with Flask

廖雪峰官网 之 使用SQLite(关于占位符)

 

后续

上面的方法很简单,在Flask提供的扩展中,有一个叫做SQLAlchemy的,使用它可以更高效地操作各种数据库,所以,下一步就是学习并使用它了。

官方文档SQLAlchemy in Flask中有介绍,看过一遍了,现在,该实践了。

 

前面做的项目都是基于单个的模型文件的,后面需要升级:基于package的方式、使用Blueprint,这两个是重点啊!

 

在官网的Tutorial会有关于SQLAlchemy、Blueprint的介绍,也是需要参考的。

 

Flask,还需要以周计的时间才能熟练使用啊。

 

自己没有做过完整的Web应用,在URL设计等方面存在一些挑战,因此,这个测试项目才会如此simple。

本来还想实现用户登录、退出等“稍微复杂”的功能的——最初的想法,最后都只能放弃了。

我想,在熟悉了SQLAlchemy、Blueprint后,Web开发的功力会有很大提高的。

 

对了,还有就是 怎么提供数据接口给前端,比如RESTful API等,都是需要熟练的。


推荐阅读
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文介绍了一个Java猜拳小游戏的代码,通过使用Scanner类获取用户输入的拳的数字,并随机生成计算机的拳,然后判断胜负。该游戏可以选择剪刀、石头、布三种拳,通过比较两者的拳来决定胜负。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 本文提供了关于数据库设计的建议和注意事项,包括字段类型选择、命名规则、日期的加入、索引的使用、主键的选择、NULL处理、网络带宽消耗的减少、事务粒度的控制等方面的建议。同时还介绍了使用Window Functions进行数据处理的方法。通过遵循这些建议,可以提高数据库的性能和可维护性。 ... [详细]
  • 获取时间的函数js代码,js获取时区代码
    本文目录一览:1、js获取服务器时间(动态)2 ... [详细]
  • TableAPI报一下异常:FieldtypesofqueryresultandregisteredTableSink
    报错信息如下:Exceptioninthread“main”org.apache.flink.table.api.ValidationException:Fieldtypesofq ... [详细]
author-avatar
黄家驹1994
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有