接着上一篇文章记录:
在flask-sqlalchemy中,数据的增删改查均由数据库的会话管理的,会话用db.session 来表示。
在准备把数据写入数据库前,要先将数据添加到会话中去,然后调用commit( ) 方法提交会话。
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config.from_object('setting.my_config')
db = SQLAlchemy(app)
class Book(db.Model):
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
username = db.Column(db.String(20),nullable=False)
userpassword = db.Column(db.String(20),nullable=False)
db.create_all(app=app)
一、更新数据库
这个方法是先删除所有数据,原有的数据都会被清除,然后在创建一个新的表 (此方法在练习的时候可以用一用)
db.drop_all() # 清除数据库中所有数据
db.create_all(app=app)
二、数据添加到数据库
在构建的模型类中,使用关键字参数定义数据,然后把定义的实例对象全部添加到会话中去,使用commit( ) 方法把会话提交到数据库中。
user_1 = Book(username = "吕星辰",userpassword = 123,useraddress = '烟台') # 定义数据
user_2 = Book(username = "吕小辰",userpassword = 123456,useraddress = '威海') # 定义数据
user_3 = Book(username="呵呵",userpassword='jkla3412',useraddress="外星球") # 定义数据
db.session.add_all([user_1,user_2,user_3]) # 把对象添加到会话中去
db.session.commit() # 把对象提交到数据库,使用 commit()提交会话
此时刷新数据库,数据已被添加进去( 我用的是数据库可视化工具Navicate )
补充:
上边代码,db.session.add_all( ) 参数必须是一个可遍历的列表list,这点从源码中也能看出来:
否则将会报错:xxx不是一个可迭代的对象
数据添加数据库方法二:
此方法解放人力!你不需要一条一条的把数据放入到模型中去,而是通过hasattr和setattr动态添加即可。。。
from flask import Flask
from flask_sqlalchemy import SQLAlchemy # 导入flask封装的sqlalchemy
app = Flask(__name__)
app.config.from_object('setting') # 导入数据库连接配置
db = SQLAlchemy(app) # 实例化sqlalchemy
class Book(db.Model): # 继承db的模型类
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
title = db.Column(db.String(20),nullable=False) # 是否可以不存在
author = db.Column(db.String(20),default="吕星辰") # 默认是··· ···
phone = db.Column(db.String(20),nullable=False)
# 遍历获取到的数据,为模型动态赋值
def set_attr(self,get_data):
if isinstance(get_data,dict):
for item in get_data.items(): # item 最后遍历出来的是 ('key','value') ··· ···
if hasattr(self,item[0]) and item[0] != 'id': # id不被赋值,因为它是主键
setattr(self,item[0],item[1])
else:
raise Exception('{0} MUST BE DICT'.format(get_data))
db.drop_all()
db.create_all(app=app)
data = {'title':'生死河','author':'吕小辰','phone':'13181706133'}
book = Book()
book.set_attr(data)
db.session.add_all([book])
db.session.commit()
三、查询数据库
flask-sqlalchemy 为每一个模型都提供了query对象,用于查询数据库
1、查询全部数据
注意:因为查询出来的数据是一个列表,所以不能够直接通过 result.username来获取数据,需要遍历,或者通过 result[ 0 ]的方式来取到某个表(这个表其实就是一个对象)!!!!!!!!!
get()则返回的是单个的对象
result = Book.query.all()
print(result) # [<Book 1>, <Book 2>, <Book 3>] 结果是一个列表list,里边是所有的表,我们通过循环,拿到每个表中的数据
for i in result:
print(i.username) # 把每个表中的username 输出
# 吕星辰
# 吕小辰
# 鸡小西
2、如果你不想每次查询出数据之后遍历,可以在创建的模型类中添加 __repr__函数 ,直接返回username,这样直接输出result的结果就是由具体数据组成的列表了。。。关于__repr__函数我会在下一篇文章中详细介绍!!!
class Book(db.Model):
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
username = db.Column(db.String(20),nullable=False)
··· ···
def __repr__(self):
return self.username
3、根据筛选条件来查询
filter( ) 过滤器方法是查询的结果进行过滤,括号中是条件判断;下边是查询 username 是'吕星辰' 的所有账户名,后边all( ) 符合条件的数据全都查出来:
res = Book.query.filter(Book.username == '吕星辰').all()
print(res) # [<Book 1>]
下边是把所有符合条件的第一个数据查出来,因为数据库中只有一条username=‘吕星辰’的数据,所以只显示一个对象:
res = Book.query.filter(Book.username == '吕星辰').first()
print(res) # [<Book 1>]
补充:
关于查询数据库除了filter,还有以下过滤器:
过滤器 | 说明 |
---|---|
filter() | 把过滤器添加到原查询上, 返回一个新查询 |
filter_by() | 把等值过滤器添加到原查询上, 返回一个新查询 |
limit() | 使用是zing的值限制原查询返回的结果数量, 返回一个新查询 |
offset() | 偏移原查询返回的结果, 返回一个新查询 |
order_by() | 根据指定条件对原查询结果进行排序, 返回一个新查询 |
group_by() | 根据指定条件对原查询结果进行分组, 返回一个新查询 |
查询执行函数:
方法 | 说明 |
---|---|
all() | 以列表形式返回查询的所有结果 |
first() | 以列表形式返回查询的第一个结果,如果没有结果,则返回 None |
first_or_404() | 返回查询的第一个结果,如果未查到,返回404 |
get() | 返回指定主键对应的行,如不存在,返回None |
get_or_404() | 返回指定主键对应的行,如不存在,返回404 |
count() | 返回查询结果的数量 |
paginate() | 返回一个Paginate对象,它包含指定范围内的结果 |
四、修改数据库中的数据
先获取数据,然后在修改数据,修该完需要提交数据。
1、使用get( )方法, 根据id( 主键 )来获取对应行数据,如果没有则返回None
res = Book.query.get(3)
res.username = "鸡小西"
db.session.commit()
res = Book.query.get(10)
print(res) # None
2、使用filter过滤器,把过滤出来的数据重新赋值,然后提交会话:
之前说过res是一个列表,所以我用[ ] 的方式来获取列表中的对象
res = Book.query.filter(Book.username == "吕小辰").all()
res[0].username = '张大力'
db.session.commit()
五、删除数据库中某些数据
与修改数据库数据流程一样,需要先查找到数据,然后进行删除,最后提交回话:
# 删除username 是 ‘张大力’的这条数据
res = Book.query.filter(Book.username == "张大力").first()
db.session.delete(res)
db.session.commit()
六、数据库会话回滚
通过db.session.rollback( ) 方法可实现在会话前数据库的状态
db.session.rollback()