一. 在flask中使用原生的SQL进行操作
(1)首先在mysql数据库中创建一个新的库flaskdatabase
create database if not exists flaskdatabase
(2) 安装pymysql
pip install pymysql
(3) 安装flask-SQLalchemy
pip install flask-sqlalchemy
(4) 配置数据库
SQLALCHEMY_DATABASE_URI='mysql+pymysql://mysql用户名:密码@主机名:端口号/数据库名'
示例:
from sqlalchemy import create_engine
# 数据库的配置
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:root@localhost:3306/flaskdatabase'
# 创建数据库引擎
engine = create_engine(SQLALCHEMY_DATABASE_URI)
with engine.conect() as con:
# 创建表
con.execute('create table user(id int primary key auto_increment, name varchar(32))')
# 插入语句
con.execute('insert into user(name) values("abc")')
# 查询语句
retdata = con.execute('select * from user')
for i in res:
print(i) # 以元组的形式返回 例如: (1,'abc')
二. 使用ORM模型
(1) 在flask中配置数据库
可以配置mysql数据库如下:
from flask_script import Manager
from flase_sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy(app) # 实例化对象
manage = Manager()
# 数据库的配置
DB_URI = 'mysql+pymysql://root:root@localhost:3306/flaskdatabase'
app.config['SQLALCHEMY_DATABASE_URI'] = DB_URI
可以配置sqlite数据库如下:
# 数据库的配置
path=os.path.join(os.path.abspath(os.path.dirname(__file__)),"sql.sqlite")#在当前目录下的sql.sqlite
app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///" + path # 三条/线
(2) 常见的字段类型和约束条件
类型名 | python中的类型 | 说明 |
---|---|---|
Integer | int | 存储整形 |
SmallInteger | int | 最小整形 |
BigInteger | int | 长整型 |
Float | float | 存储浮点型 |
String | str | 不定长的存储字符类型 |
Text | str | 存储长文本类型 |
Boolean | Bool | 存储布尔类型 |
Date | datetime.date | 存储日期 |
Time | datetime.time | 存储时间 |
Datetime | datetime.datetime | 存储日期和时间 |
约束条件:
约束 | 说明 |
---|---|
primary_key | 主键索引, 是否设置为主键,默认为False |
unique | 唯一索引, 默认为False |
index | 常规索引, 默认为False |
nullable | 是否可以为空, 默认为True |
default | 设置默认值 |
(3) 创建模型
1.创建模型类
from flask_script import Manager
from flase_sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy(app) # 实例化对象
manage = Manager()
class Students(db.Model):
__tablename__ = '表名' # 此属性可以为数据库表在创建的时候重新命名
id = db.Column(db.Integer, primary_key=True)
sname = db.Column(db.Stirng(32),index=True,unique=True) # 设置常规和唯一索引
sage = db.Column(db.Interger)
sgender = db.Column(db.Boolean, default=True)
sinfo = db.Column(db.String(50))
2. 表的操作
@app.route('/createtable/')
def createtable():
db.create_all() # 创建表
return "创建表"
@app.route('/droptable/')
def droptable():
db.drop_all() # 删除表
return '删除表'
3. 对数据的增删改查
插入数据:
@app.route('/insert/')
def insert():
try:
dataone = Student(sname='zs',sage=18,sgender=True,sinfo='个人简介')
db.session.add(dataone)
db.session.commit() # sqlalchemy默认开启了事务处理,需要提交事务,数据才能更新到数据库
except:
db.session.rollback() # 如果插入数据失败,回滚
return '数据插入操作'
查询操作:
@app.route('/select/')
def select():
data = Students.query.get(1) # 获取id为1的对象
print(data) # <user 1>
print(data.sname) # zs
print(data.sage) # 18
return '查询数据'
修改数据:
@app.route('/update/')
def update():
data = Students.query.get(1)
data.sname = 'lisi'
db.session.add(data) # 修改
db.session.commit() # 提交事务
return '修改数据'
删除数据:
@app.route('/delete/')
def delete():
data = Students.query.get(1)
db.session.delete(data)
db.session.commit() # 提交事务
return '删除数据'
三. 对上述的增删改查自定义一个基础类
通过自定义一个类, 封装add和commit, 可以做到仿Django
一样的操作
models.py文件中的代码
class DBchoice:
# 保存和修改的方法
def save(self):
try:
db.session.add(self) # 添加对象到数据库,self代表当前类的实例
db.session.commit()
return True # 如果添加成功返回True
except:
db.session.rollback()
return False
# 添加多个的方法
@classmethod
def saveall(cls,attr):
try:
db.session.add_all(attr)
db.session.commit()
return True
except:
db.session.rollback()
return False
def delete(self):
try:
db.session.delete(self)
db.session.commit()
return True
except:
db.session.rollback()
return False
# DbChoice为的模型基础类
class Users(db.Model, DbChoice):
id = db.Column(...)
uusername = db.Column(...)
usex = db.Column(..)
uinfo = db.Column(..)
在视图views.py中:
# 添加数据的操作
@app.route('/insert/')
def insert():
u = Users(uusername='张三', ugender=False, uinfo='个人信息') # ugender为True代表男
# 原生的写法
# db.session.add(u)
# db.session.commit()
# 使用自定义模型类的写法
u.save()
return '添加数据'
# 修改数据的操作
@app.route('/update/')
def update():
u = User.query.get(1)
u.uusername = '李四'
# 原生的写法
# db.session.add(u)
# db.session.commit()
# 使用自定义模型类的写法
u.save()
return '修改数据'
# 删除数据
@app.route('/delete/')
def delete():
u = User.query.get(1)
# 原生的写法
# db.session.delete(u)
# db.session.commit()
# 使用自定义模型类的写法
u.delete()
return '删除数据'
四. 数据库的查询操作
查询集: 在flask中一般查询的结构会返回一个查询数据的集合.
分类:
1>原始查询集: 使用类名.query
得到的为原始查询集
2>数据查询集: 通过过滤器的方法, 过滤原始查询集得到的数据
过滤器
1. all()获取所有的数据查询集,以列表的形式返回
@app.route('/all/')
def all():
allData = User.query.all()
return render_template('xx.html', allData=allData)
2. filter() 方法
不带参数: 查询所有, 返回查询集
带参数: filter(类名.属性名 运算符 值[,类名.属性名 运算符 值])
@app.route('/filter/')
def filter():
data = Users.query.filter() # 获取所有数据的查询集
data = Users.query.filter(Users.ugender==True) # 查询性别为True
data = Users.query.filter(Users.id == 1) # 查询id为1
data = Users.query.filter(Users.id != 1) # id不为1的查询集
data = Users.query.filter(Users.id == 1, Users.ugender==True) # 多个条件并且的关系
data = Users.query.filter().first() # 只获取第一条数据 <User 1>
return 'xx'
在filter方法中可使用的运算符:
>,<,>=,<=,!=,==
3. filter_by() 方法
格式: filter_by(属性=值)
@app.route('/filter_by/')
def filter_by():
data = Users.query.filter_by(id=1) # 不用加类名
# data = Users.query.filter_by(id>1) # error 错误的写法
# data = Users.query.filter_by(id!=1) # error 错误的写法
# 同时多个条件
data = Users.query.filter_by(id=1,usex=False) # ok
return 'xxx'
关于filter()与filter_by()
- filter() 可以像写sql的where条件那样写
>,<
等条件, 但引用列名时, 需要通过类名.属性名
的方式。 - filter_by() 可以使用python的正常参数传递方法传递条件, 指定列名时, 不需要额外指定类名, 参数名对应名类中的属性名。
- 在filter_by() 只能使用等号运算符
=
4. offset(num) 偏移数据量
@app.route('/offset/')
def offset():
data = Users.query.offset(3) # 从第四条数据开始查询
# data = Users.query.offset() # error 必须要传参
data = Users.query.offset(0) # ok
return 'xx'
5. limit(num) 取出多少条数据
@app.route('/limit/')
def limit():
data = Users.query.limit(5) # 取5条数据
data = Users.query.offset(3).limit(5) # 从第四条开始取5条
retrun 'xx'
6. order_by(类名.属性名) 排序
默认按照指定字段的升序排序, 如果-类名.属性名
降序排序
@app.route("/orderby/")
def orderby():
data = Users.query.order_by(Users.id) # id升序
data = Users.query.order_by(-Users.id) # 按照id降序排序
data = Users.query.filter(Users.id>5, Users.ugender==True).order_by(-Userd.id).offset(1).limit(3)
return 'xx'
7. first() 在查询集中取出第一条数据
data = Users.query.filter().first() # <user 1>
8. get(id的值)
根据id来查询, 如果查询不到返回None
@app.route('/get/')
def get():
data = Users.query.get(1) # <user 1>
return 'xx'
9. contains() 包含
@app.route('/contains/')
def contains():
data = Users.query.filter(Users.uusername.contains('张')) # 获取用户名中包含张的
return 'xxx'
10. like模糊查询
@app.route('/like/')
def like():
data = Users.query.filter(Users.uusername.like('%三%')) # 用户名中包含三的
data = Users.query.filter(Users.uusername.like('李%')) # 用户名以李开头的
data = Users.query.filter(Users.uusername.like('%三')) # 以三结尾的
return 'xx'
11. startswith, endswith 以..开头, 以..结尾
@app.route('/func/')
def func():
data = Users.query.filter(Users.uusername.startswith('张')) # 以张开头的
data = Users.query.filter(Users.uusername.endswith('三')) # 以三结尾的
return 'xx'
12. 其他运算符
@app.route('/func/')
def func():
data = Users.query.filter(Users.id.__gt__(5)) # 查询id>5
data = Users.query.filter(Users.id.__ge__(5)) # 查询id>=5
data = Users.query.filter(Users.id.__le__(3)) # 查询id<=3的
data = Users.query.filter(Users.id.__lt__(3)) # 查询id<3的
13. in_和not in判断是否在指定..里
@view.route('in_')
def in_():
data = Users.query.filter(Users.id.in_([1,2,3,4])) # 查询id为1,2,3,4
data = Users.query.filter(~Users.id.in_([1,2,3,4])) # 查询id不为1,2,3,4,注意~取反
data = Users.query.filter(Users,id.notin_([1,2,3,4])) # id不为1,2,3,4的
return 'xx'
14. is null 为空
@app.route('/null/')
def null():
data = Users.query.filter(Users.ugender.is_(None)) # 判断性别为空的
data =Usres.query.filter(Users.ugender == None)#ok 在mysql中这种写法不正确不能判断是否为Null
return 'xx'
15. is not null 不为空
data = Users.query.filter(Users.ugender.isnot_(None)) # 查询性别不为空的
data = Users.query.filter(Users.ugender != None) # ok
逻辑查询
需要导入的方法from sqlalchemy import and_,or_,not_
# 逻辑与
data = Users.query.filter(and_(Users.ugender==True,Users.id.__lt__(3)))
data = Users.query.filter(Users.ugender==True, Users.id.__lt__(3)) # 同上
# 逻辑或
data = Users.query.filter(or_(Users.ugender==True, Users.id.__lt__(3))) # 性别为男或id小于3的
# 逻辑非
data = Users.quert.filter(not_(Users.usex == True)) # 注意not_()参数只能为一个
data = Users.quert.filter(~(Users.usex == True))
网友评论