Flask Model
使用ORM的原因:
随着项目越来越大 使用原生sql就会出现如下问题
- SQL语句重复使用率不高 越复杂的sql语句就越长 会出现很多类似的SQL语句 并且不易读
- 很多SQL语句都是在业务逻辑中拼接出来的 如果数据库需要更改 就要修改这些逻辑 就会漏掉对某些SQL语句的更改
- 容易忽略WEB安全问题(SQL注入)
好处:
- 易用性 可以有效的减少SQL语句的重复性 使语句看起来更加直观
- 设计灵活 用简单的语句就可以实现复杂的查询
- 可移植性 支持多个数据库的链接 只要更改链接方式 其它都不用
一、flask-sqlalchemy
安装:
pip3 install flask-sqlalchemy
(1) 创建数据库
create database if not exists 库名 character set utf8;
(2) 安装pymysql
pip3 install pymysql
(3) 配置数据库的链接地址
mysql
app.config[‘SQLALCHEMY_DATABASE_URI’] = ‘mysql+pymysql://username:password@host:port/database’
sqlite
app.config[‘SQLALCHEMY_DATABASE_URI’] = ‘sqlite:///数据库的路径/数据库名称.sqlite’
二、字段类型 约束条件
字段类型
类型名 | 说明 |
---|---|
Integer | 整形 |
SmallInteger | 小整形 |
BigInteger | 长整形 |
Float | 浮点形 |
String | varchar |
Text | 长文本 text |
Boolean | tinyint |
Date | 日期 datetime.date |
Time | 时间 datetime.time |
DateTime | 日期和时间 datetime.datetime |
可选约束条件
选项 | 说明 |
---|---|
primary_key | 主键 |
unique | 唯一索引 |
index | 常规索引 |
nullable | 是否为空 默认为True |
default | 默认值 |
三、创建模型
创建User模型表
from exts import db
#创建User模型
class User(db.Model):
__tablename__ = 'user' #起表名
id = db.Column(db.Integer,primary_key=True) #主键
username = db.Column(db.String(12),index=True)
password_hash = db.Column(db.String(128),default='123456')
age = db.Column(db.Integer,default=18)
sex = db.Column(db.Boolean,default=True)
email = db.Column(db.String(60),default='793390457@qq.com')
icon = db.Column(db.String(70),default='default.jpg')
confirm = db.Column(db.Boolean,default=False) #激活状态 默认不激活
def __str__(self):
return self.username
四、创建表 简单的增删改查
(1) 创建表
@app.route('/create_table/')
def create_table():
db.create_all()
return 'create_table'
(2) 删除表
@app.route('/drop_table/')
def drop_table():
db.drop_all()
return 'drop_table'
(3) 添加一条数据 add
@app.route('/insert_one/')
def insert_one():
try:
u = User(username='张三',password_hash='zhangsan123456',age=20,sex=False,email='948807313@qq.com',confirm=True)
db.session.add(u)
db.session.commit() #提交 默认开启了事物
except:
db.session.rollback() #回滚
return 'insert_one'
(4) 添加多条数据 add_all
#添加多条数据
@app.route('/insert_many/')
def insert_many():
try:
u1 = User(username='李四')
u2 = User(username='王五')
db.session.add_all([u1,u2])
db.session.commit() #提交 默认开启了事物
except:
db.session.rollback() #回滚
return 'insert_many'
(5) 查询一条数据 get
@app.route('/select_one/')
def select_one():
u = User.query.get(1)
print(u.username)
print(u.age)
print(u.sex)
return 'select_one'
(6) 修改一条数据 add
#修改数据
@app.route('/update/')
def update():
u = User.query.get(1)
u.username = '赵六'
u.age = 30
u.sex = True
db.session.add(u)
db.session.commit()
return 'update'
(7) 删除一条数据 delete
#删除数据
@app.route('/delete/')
def delete():
u = User.query.get(1)
db.session.delete(u)
db.session.commit()
return 'delete'
五、更改保存的方式
(1) 更改配置参数
app.config[‘SQLALCHEMY_COMMIT_ON_TEARDOWN’] = True
(2) 自定义表单基类
from exts import db
class ModelBase:
# 添加一条数据
def save(self):
try:
db.session.add(self)
db.session.commit() # 提交 默认开启了事物
except:
db.session.rollback() # 回滚
# 添加多条数据
@staticmethod
def saveAll(*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模型
class User(ModelBase,db.Model):
...
使用
#添加一条数据
@view.route('/insert_one/')
def insert_one():
u = User()
u.username = '张聚全'
u.save()
return 'insert_one'
import random
#添加多条数据
@view.route('/insert_many/')
def insert_many():
lastname = ['张','王','赵','钱','孙','李','周','吴','郑']
firstname = ['文','超','峰','兴','尧','秀','良','程','天','玉']
name1 = lastname[random.randrange(len(lastname))]+firstname[random.randrange(len(firstname))]+firstname[random.randrange(len(firstname))]
name2 = lastname[random.randrange(len(lastname))]+firstname[random.randrange(len(firstname))]+firstname[random.randrange(len(firstname))]
u1 = User(username=name1,sex=random.randint(0,1),age=random.randint(0,100))
u2 = User(username=name2,sex=random.randint(0,1),age=random.randint(0,100))
User.saveAll(u1,u2)
return 'insert_many'
#修改数据
@view.route('/update/')
def update():
u = User.query.get(2)
u.username = '王老七'
u.age = 28
u.sex = False
u.save()
return 'update'
#删除数据
@view.route('/delete/')
def delete():
u = User.query.get(2)
u.delete()
return 'delete'
六、查询集
分类:
-
原始查询集
没有经过条件筛选的查询称之为原始查询集
-
数据查询集
通过过滤器的方法称之为数据查询集
过滤器特点:
链式调用
(1) all() 以列表形式返回所有对象
类名.query.all()
@view.route('/filter/')
def filter():
data = User.query.all()
print(data)
return render_template('show.html',data=data)
(2) filter() 过滤查询默认所有
运算符的值
>
<
>=
<=
==
!=
类名.query.filter([条件])
data = User.query.filter(User.sex==True,User.age<20) #查询性别为True and 年龄小于20
data = User.query.filter()#查询所有
(3) filter_by() 只支持单条件查询 默认查询所有
类名.query.filter_by(**kwargs)
data = User.query.filter_by()
data = User.query.filter_by(sex=True)
data = User.query.filter_by(sex=True,age=18)
(4) offset(num) 偏移值的num条
data = User.query.offset(5)
(5) limit(num) 取出num条数据
data = User.query.limit(5)
(6) offset limit
data = User.query.offset(5).limit(5)
(7) order_by 排序
排序
- 默认升序
- -降序
实例
data = User.query.order_by(User.age)
data = User.query.order_by(-User.age)
(8) first() 取出第一个对象
data = User.query.order_by(-User.age).first()
data = User.query.first()
(9) get(id值) 根据id查询数据返回对象 不存在 返回None
data = User.query.get(1)
(10) contains() 包含关系(模糊查询)
data = User.query.filter(User.username.contains('张'))
(11) like 模糊查询
data = User.query.filter(User.username.like('%张%'))
data = User.query.filter(User.username.like('张%'))
data = User.query.filter(User.username.like('%张'))
data = User.query.filter(User.username.like('%超'))
(12) startswith endswith 以…开头 以…结尾
data = User.query.filter(User.username.startswith('王'))
data = User.query.filter(User.username.endswith('文'))
(13) 比较运算符
__gt__
__ge__
__lt__
__le__
data = User.query.filter(User.age.__gt__(30))
(14) in 和 not … in …
data = User.query.filter(User.age.in_([10,20,30,40,18,91]))
data = User.query.filter(User.age.notin_([10,20,30,40,18,91]))
(15) null 和 not null
data = User.query.filter(User.username.is_(None))
data = User.query.filter(User.username==None)
data = User.query.filter(User.username!=None)
data = User.query.filter(User.username.isnot(None))
(16) and_
导入:
from sqlalchemy import and_
data = User.query.filter(and_(User.sex==True,User.age==18))
data = User.query.filter(User.sex==True,User.age==18)
data = User.query.filter(User.sex==True).filter(User.age==18)
(17) or_
导入:
from sqlalchemy import or_
data = User.query.filter(or_(User.sex==True,User.age==18))
(18) not_
导入:
from sqlalchemy import not_
data = User.query.filter(not_(User.sex == True))
(19) count 统计
data = User.query.filter().count()
(20) concat 连接
data = User.query.order_by(-Posts.path.concat(Posts.id))
七、迁移
安装
pip3 install flask-script
pip3 install flask-migrate
使用
from flask_script import Manager
from flask_migrate import Migrate,MigrateCommand
manager = Manager(app,db)
migrate = Migrate(app)
manager.add_command('db',MigrateCommand)
运行