BlackA,Talk is cheap,Show me the code.
上一节我们学习了 FLask-SQLAlchemy 的安装,如何将 Flask-SQLAlchemy 框架连接到数据库,以及如何创建一个模型并添加模型与表的映射,在接下来的这一节中我们将进一步学习如何使用 Flask-SQLAlchemy 框架对数据库进行 增、删、改、查 等基本操作。
插入(INSERT )操作是指在数据库中添加一条新的记录,或是在空的数据库中新增一条记录。在 Flask-SQLAlchemy 框架中,向数据库中插入数据分为以下三个步骤:
1. 创建一个 Python 对象
2. 把新建的对象添加到会话
3. 提交会话
注意:这里的会话不是 Flask 的会话,而是 Flask-SQLAlchemy 的会话。其本质上是一个数据库事务的加强版本。下面这个例子展示了如何向数据库中插入一条记录(即一般网站的注册功能):
from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///mydb.db" db = SQLAlchemy(app) # 创建模型 # 这里的模型表示用户信息 class User(db.Model): __tablename__ = "User" # 用户 id 字段(整数、主键、自动增长) id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 用户姓名字段(字符串、非空) user_name = db.Column(db.String(50), nullable=False) # 用户密码字段(字符串、非空,实际应用时需要加密存储) user_pass = db.Column(db.String(50), nullable=False) # 别忘了创建表 db.create_all() # 注册界面,因为我们还没有学习 get 和 post,这里使用 url参数模拟 # user_name 表示用户名,user_pass 表示用户密码 @app.route("/register/<user_name>/<user_pass>") def register(user_name, user_pass): # 创建一个新的 Python 对象表示新用户 new_user = User(user_name=user_name, user_pass=user_pass) # 把新建的对象添加到会话,即插入记录的实际操作 db.session.add(new_user) # 提交会话(事务) db.session.commit() return "成功添加用户:{},用户名:{},密码:{}".format( new_user.id, new_user.user_name, new_user.user_pass) if __name__ == '__main__': app.run(debug=True)
程序首先声明了一个模型 User,也就是在数据库新建立了一张表,用于表示用户信息;之后程序定义一条路由规则,因为我们还没有学习 get 和 post 网络请求,所以这里使用了以前学过的 url参数 来模拟注册界面。然后程序新建一个 python 对象,表示新注册的用户(ORM中一个 python 对象就对应关系数据库中的一条记录),并把新建的对象添加到会话中。在把对象添加到会话之前,Flask-SQLAlchemy 不会把它(新建的 python 对象)实际的插入到数据库中,这样使你仍可以放弃修改(比如在一个页面上创建文章草稿,只把文章传递给模板来渲染,而不把它存进数据库)。
调用 db.session.add() 函数会添加记录到数据库中。它会发出一个 INSERT 语句给数据库,但是由于事务仍然没有提交,数据库仍没有发生改变,使用db.session.commit() 函数将事务提交到数据库,此时自动增长的 id 字段将获得其值。下面是程序的运行结果:
学习完了如何插入记录据之后,我们来学习一下如何查询记录。查询(SELECT)操作是在数据库中筛选所有符合条件的记录,是删除和修改记录的前提。在 Flask-SQLAlchemy 中,查询操作是通过db.Model类的属性 query 实现的,这是一个查询对象,可以使用`filter()`方法来过滤条件(相当于SQL中的WHERE语句),通过all() 或者first() 方法来发起查询。下面这个程序实现了查询用户功能:
# 查询界面 # user_name 表示要查询的用户名 @app.route("/find/<user_name>") def find(user_name): # 查询符合条件的用户 user1 = User.query.filter( User.user_name == user_name).first() # 也可以使用下面这种写法 # user1 = User.query.filter( # User.user_name == user_name)[0] return "用户ID:%d,用户姓名:%s,用户密码:%s" % ( user1.id, user1.user_name, user1.user_pass)
User.query.filter()方法接受一个条件作为参数,并返回一个BaseQuery类型的对象,这个对象包括了查询对应的SQL语句,可以用first()方法和all()方法实际发起查询,这两个方法分别返回符合条件的第一条记录或全部记录构成的列表(这里的记录都是指ORM中记录对应的 Python 对象),当没有查询到结果时会返回None。
除了使用first()和all()方法以外,也可以使用列表切片的方式来获得查询结果,唯一的不同是当没有查询到结果时列表切片的方式会抛出一个IndexError异常。有关查询的更多内容可以参考官方文档。下面是这个程序的运行结果:
修改(`UPDATE`)记录十分简单,主要分为一下三步:
1. 查询出要修改的记录(Python对象)
2. 修改数据(Python对象)
3. 提交会话
下面我们来实现程序的修改用户密码功能:
# 修改功能 # user_name 表示要修改的用户名,new_pass 表示修改的新密码 @app.route("/update/<user_name>/<new_pass>") def update(user_name, new_pass): # 查询记录 user1 = User.query.filter( User.user_name == user_name).first() # 如果没有查询到结果 if user1 is None: return "查无此人!" else: # 修改数据 user1.user_pass = new_pass # 提交会话 db.session.commit() return "成功修改%s的密码为%s" % ( user1.user_name, user1.user_pass)
下面是这个程序的运行结果:
删除(`DELETE`)操作也十分简单,同样分为三步:
1. 查询出要删除的记录(Python对象)
2. 删除记录(Python对象)
3. 提交会话
下面实现了程序的删除用户功能:
# 删除功能 # user_name 表示要删除的用户名 @app.route("/delete/<user_name>") def delete(user_name): # 查询记录 user1 = User.query.filter( User.user_name == user_name).first() if user1 is None: return "查无此人!" else: # 删除记录 db.session.delete(user1) # 提交会话 db.session.commit() return "成功删除用户%s" % user1.user_name
下面是这个程序的运行结果: