一、Model对数据的操作3种办法
(1) 最原始的 提交 和 回滚
#最原始的添加 提交或者回滚 每次都需要
@test.route('/insert_one/')
def insert_one():
try:
# u = User(username='zhangshang',sex=False,age=18)
u = User('lisi',True,20)
db.session.add(u)
db.session.commit()
except:
db.session.rollback()
return 'insert_one'
注意:
每次都需要提交和回滚
(2) 在settings.py进行配置
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
每次添加或者保存,修改,删除数据 都不需要commit() 或者 rollback()
实例
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True #设置自动提交
#settings.py已经设置为数据自动提交
@test.route('/auto_insert_one/')
def auto_insert_one():
u = User('王五',False,30)
db.session.add(u)
return 'insert_one'
(3) 自定义增删改的基类 进行封装
user.py中base类的书写
class Base:
#添加一条数据
def save(self):
try:
db.session.add(self)
db.session.commit()
except:
db.session.rollback()
#添加多条数据
@staticmethod
def save_all(*args):
try:
db.session.add_all(args)
db.session.commit()
except:
db.session.rollback()
#自定义删除基类
def delete(self):
try:
db.session.delete(self)
db.session.commit()
except:
db.session.rollback()
user.py中base类的使用
class User(Base,db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer,primary_key=True)
username = db.Column(db.String(12),index=True)
sex = db.Column(db.Boolean,default=True)
age = db.Column(db.Integer,default=20)
icon = db.Column(db.String(40),default='default.jpg')
def __init__(self,username,sex=True,age=18,icon='default.jpg'):
self.username = username
self.sex = sex
self.age = age
self.icon = icon
蓝本文件中的使用
#使用自定义的base类 进行添加 自带提交和回滚
@test.route('/self_insert_one/')
def self_insert_one():
u = User('兆六',False,20)
u.save()
return 'insert_one'
#添加多条数据
@test.route('/self_insert_many/')
def self_insert_many():
sex = [True,False]
u1 = User(random.randrange(1000,10000),sex[random.randint(0,1)],random.randint(1,100))
u2 = User(random.randrange(1000,10000),sex[random.randint(0,1)],random.randint(1,100))
User.save_all(u1,u2)
return '添加多条'
#自定义删除方法的使用
@test.route('/delete/')
def delete():
u = User.query.get(2)
u.delete()
return '删除'
#自定义修改方法的使用
@test.route('/update/')
def update():
u = User.query.get(2)
u.username = '张三'
u.save()
return '修改'
二、数据的操作
查询集: 数据查询的集合
分类:
原始查询集
就是没有经过过滤器筛选的集合
数据查询集
经过过滤器筛选 最终拿到你的数据的集合
过滤器 链式调用
如: a().b().c()
(1) all() 以列表的形式 得到数据查询集
使用
@test.route('/all/')
def show():
dataList = User.query.all()
print(dataList) #[<user 1>,<user 2>...]
return render_template('show.html',data=dataList)
(2) filter() 过滤出你要得到的数据
如果没有参数 默认查询所有
User.query.filter(User.username=='张',User.sex==True) #查询name为张 并且sex为True
@test.route('/filter/')
def filter():
data = User.query.filter() #查询所有
data = User.query.filter(User.sex==True) #查询性别为True
data = User.query.filter(User.sex==True,User.age==43) #查询性别为True and age为43
print(data)
return render_template('show.html',data=data)
(3) filter_by() 只支持单条件查询 =
#单条件查询
@test.route('/filter_by/')
def filter_by():
data = User.query.filter_by() #查询所有
data = User.query.filter_by(sex=True) #查询sex为True的数据
data = User.query.filter_by(sex=True,age=43) #查询sex为True 并且 age为43的数据
print(data)
return render_template('show.html', data=data)
注意:
因为 filyter_by的参数为**kwargs 所以只能使用关键字参数
(4) offset(num) 偏移量 偏移几条数据
#offset 偏移量
@test.route('/offset/<int:num>/')
def offset(num):
data = User.query.offset(num)
return render_template('show.html', data=data)
(5) limit(num) 取出num条数据
#limit 偏移量
@test.route('/limit/<int:num>/')
def limit(num):
data = User.query.limit(num)
return render_template('show.html', data=data)
(6) offset().limit() 组合使用
@test.route('/offsetlimit/<int:num>/')
def offsetlimit(num):
data = User.query.offset(num).limit(num)
return render_template('show.html', data=data)
(7) order_by() 排序 升序/降序
- 升序 类名.属性名
- 降序 -类名.属性名
#order_by 排序
@test.route('/order_by/')
def order_by():
# data = User.query.order_by(User.id)
# data = User.query.order_by(-User.id)
# data = User.query.filter_by(sex=True).order_by(-User.id)
data = User.query.order_by(-User.age).limit(1)
return render_template('show.html', data=data)
(8) first() 取出第一条数据
#取出第一条数据
@test.route('/first/')
def first():
data = User.query.order_by(-User.id).first() #== data = User.query.all()[0]
print(data)
return 'first'
(9) get() 根据id查询
@test.route('/get/')
def myGet():
data = User.query.get(20)
print(data)
return 'get'
注意:
如果查询不到 则为None 否则返回对象
(10) contains() 包含关系
就是模糊查询
@test.route('/contains/')
def contains():
data = User.query.filter(User.username.contains('1'))
return render_template('show.html', data=data)
(11) like 模糊查询
@test.route('/like/')
def like():
data = User.query.filter(User.username.like('%1%')) #包含1
data = User.query.filter(User.username.like('%1')) #1结尾
data = User.query.filter(User.username.like('1%')) #1开头
return render_template('show.html', data=data)
(12) startswith endswith 以...开头 以...结尾
@test.route('/startend/')
def startend():
data = User.query.filter(User.username.startswith('张')) #以张作为开头
data = User.query.filter(User.username.endswith('六')) #以六作为结尾
return render_template('show.html', data=data)
(13) 比较运算符
__gt__
大于__ge__
大于等于__lt__
小于__le__
小于等于>
<
>=
<=
==
!=
data = User.query.filter(User.sex!=True) #查询所有
data = User.query.filter(User.sex!=True,User.age>=30) #查询所有
data = User.query.filter(User.age.__gt__(30)) #查询所有
data = User.query.filter(User.age.__ge__(30)) #查询所有
data = User.query.filter(User.age.__lt__(30)) #查询所有
data = User.query.filter(User.age.__le__(30)) #查询所有
data = User.query.filter(User.age.__gt__(30),User.age.__lt__(70)) #查询所有
(14) in_ 和 not in
@test.route('/in/')
def myIn():
data = User.query.filter(User.id.in_([1,2,3,4])) #in
data = User.query.filter(~User.id.in_([1,2,3,4])) #not in
return render_template('show.html', data=data)
(15) 查询为null的数据
@test.route('/null/')
def null():
data = User.query.filter(User.username.is_(None))
data = User.query.filter(User.username == None)
data = User.query.filter(~User.username.isnot(None))
(16) 查询不为null的
@test.route('/notnull/')
def notnull():
data = User.query.filter(User.username!=None)
data = User.query.filter(~User.username.is_(None))
data = User.query.filter(User.username.isnot(None))
(17) 逻辑与查询 and_
- 多个条件 逗号隔开
- from sqlalchemy import and_
实例
from sqlalchemy import and_
@test.route('/and/')
def myAnd():
#查询性别为True 并且名字包含1的数据
data = User.query.filter(User.username.contains('1'),User.sex==True)
data = User.query.filter(and_(User.username.contains('1'),User.sex==True))
data = User.query.filter(User.username.contains('1')).filter(User.sex==True)
return render_template('show.html', data=data)
(18) 逻辑或 or_
from sqlalchemy import or_
@test.route('/or/')
def myOr():
#or的使用
data = User.query.filter(or_(User.username.contains('1'),User.sex==True))
#and 和 or使用
data = User.query.filter(or_(User.username.contains('1'),User.sex==True),User.age>=60)
return render_template('show.html', data=data)
(19) 逻辑非 not_
from sqlalchemy import not_
@test.route('/not/')
def myNot():
# data = User.query.filter(not_(User.username.contains('1')))
# data = User.query.filter(~(User.username.contains('1'),User.sex==True)) #错误写法
data = User.query.filter(~(User.username.contains('1')))
return render_template('show.html', data=data)
注意:
not_和~都只能给一个条件进行取反
(20) count() 统计个数
@test.route('/count/')
def count():
data = User.query.filter().count()
print(data)
return '{}'.format(data)
三、文件的迁移(falsk-migrate)
(1) 安装
pip install flask-migrate
(2) 创建迁移对象
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
db = SQLAlchemy(app) #ORM实例化
migrate = Migrate(app,db) #实例化迁移类
from flask_migrate import MigrateCommand
manager.add_command('db',MigrateCommand) #将迁移的命令添加到终端运行解析器 通过命令进行迁移
(3) 创建迁移目录
python3 manage.py db init
(4) 生成迁移文件
python3 manage.py db migrate
(5) 执行迁移文件
python3 manage.py db upgrade
注意:
- 如果生成迁移文件的时候报错了,将migrations目录中的版本号文件删除掉,将数据库中的迁移文件版本号的表也删除掉。
- 如果在生成迁移文件的时候告诉你,当前模型没有任何的改变,那么可能是没有检测到模型的存在,此时去导入一下再重新生成迁移文件(这个问题不是只有flask有 在django也可能遇到)。
评论 (0)