flask_sqlalchemy 是绑定数据库并进行映射的库
使用这个库的必要流程如下(不考虑命令行迁移的内容)
1. from flask_sqlalchemy import SQLAlchemy # 引入函数
2. db=SQLAlchemy() # 实例化
3. db.init_app(app)#绑定到主APP
4. class User(db.Model):#定义下模型类,这里注意继承db.Model
********************
********************
********************
5. user1=User()#模型类实例化
6. db.session.add(user1)#具体方法这个是新增方法,写入缓存
7. db.session.commit()#刷入数据库完成一个最简流程
以上方法是配合我之前的两篇文章《从虚拟环境到MYSQL 映射绑定配置》
里边的方式,手动操作本地创建文件和版本号的flask_sqlalchemy使用方法,所以本方法不能单独使用。要配合以下库联合使用
安装pymysql 1.0.2
pip install pymysql
安装flask-script
pip install flask-script
安装 flask-migrate 注意使用版本2.5.3 否则没有MigrateCommand命令
pip install flask-migrate
下面是带上数据库迁移和命令行两个模块的基本最简写法了,就在一个文件里还带了FLASK主体。
from flask import Flask
from setting import Config
from flask_migrate import Migrate,MigrateCommand
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy
db=SQLAlchemy()
class Sk(db.Model):#模型类
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
name=db.Column(db.String(30),nullable=False)
say=db.Column(db.String(100),nullable=False)
def __str__(self):
return self.name
app = Flask(__name__)
app.config.from_object(Config) #配置
manage = Manager(app) #命令行
migrate=Migrate(app,db) #数据库迁移
manage.add_command('db',MigrateCommand) #数据库映射
db.init_app(app) #数据库映射绑定
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
manage.run()
关于flask_sqlalchemy的增删查改
tips避坑指南~这里记录一个坑
if request.method=='POST':
u1=User() #这里实例化了以后
username=request.form.get('name')
u1_all=u1.query.filter(u1.name==username).first() # u1.query以及u1.name这里就不行,他不报错但是查询为空也就是语句不工作
调整为下面这样,直接用User.query以及User.name则正常
if request.method=='POST':
u1=User()
username=request.form.get('name')
u1_all=User.query.filter(User.name==username).first()
以上务必注意
首先是----------》 查
- all 结果是所有
- get 结果是一个
- filter_by 里面是等值
user1.query.filter_by(User1.username= 'gao').flist()
- filter 里面是灵活的条件 《重点在这里》
user1.query.filter(User1.username=='gao').flist() #all() ,first()
user1.query.filter(User1.age>18).flist()#查询可以是条件
user1.query.filter(User1.username=='gao').all()
》》》 关于模糊查询like
user1.query.filter(User1.username.like('%高%')).all() #like括号内和原生数据库写法一致 %表示多个 ,_ 底杠表示一个 .
》》》多条查询采用函数形式 或者条件为: or_
》》》并且条件为:and_
》》》非条件为:not_
》》》使用前先导入
from sqlalchemy import or_,and_,not_ #注意看看是从哪里导入的条件函数
user1.query.filter(or_(User1.username.like('%高%'),User1.username.like('%大%'))).all()
user1.query.filter(and_(User1.username.like('%高%'),User1.username.like('%大%'))).all()
user1.query.filter(not_(User1.username.like('%高%'))).all()
》》》比较查询:在filter括号内,可以比较大小的可以直接使用比较符合比如 ’< ‘ , ‘>’ ‘!=’ ‘>=’ ‘<=’ 等符号
》》》多个值查询:in_ 这个是列表检索用法是
user1.query.filter(User1.username.in_([ 列表])).all()
》》》排序:查询结果后用 .order_by(’age’)
如果想结果是个列表需要加个.all()
.order_by(‘age’).all()
逆序查询就加个-
例如这样 .order_by(‘-age’)
全部排序的写法:
.query.order_by().all()
》》》限制:limit (分页的时候使用)
使用: limit +offset
.offset(2).limit(2).all()# offset:跳过2条记录 limit:获取两条 all:返回内容转成列表。
然后是----------》 删
》》》 逻辑删
用一个删除标志位表示删除,比较简单。只是要注意:在任何查询时都要加删除标志判断后再显示结果
》》》物理删
u1= User.query.filter_by(phone =phone_1).first() # 查出条目
db.session.delelte(u1) #物理删除指令
db.session.commit() # 刷入数据库执行
----------》 改,逻辑是条件查询查出唯一条目转成列表然后带上点和名直接赋值即可。最后记得执行刷新指令刷入数据库。
u1= User.query.filter_by(phone =phone_1).first()
u1.username=request.form.get('username') # 从网页中获取的用户名数据直接替换模型类的相应数据
u1.password=request.form.get('password')
u1.phone=request.form.get('phone')
db.session.commit()
补充:一个常用的flask密码加密的方式
from werkzeug.security import generate_password_hash # 密码加密引入
data_hash=generate_password_hash(data)# 用法就这样
分页查询补充:Pagination对象可以方便的进行分页
#分页查询必须要取得待查页码,这个页码记得处理成数字
page = request.args.get('page', 1, type = int)#get取'page'的值,默认是整数1
#获取pagination对象
pagination = data.query.order_by(data.timestamp.desc()).paginate(page, per_page=3, error_out = False) #排个序,输入页码,查询3条数据。
#pagination对象仅仅是个对象,用items方法可以返回里边的全部内容
posts = pagination.items
pagination对象还有以下常用方法:
has_next :是否还有下一页,布尔值
has_prev :是否还有上一页,布尔值
items : 返回当前页的所有内容
next(error_out=False) : 返回下一页的Pagination对象
prev(error_out=False) : 返回上一页的Pagination对象
page : 当前页的页码(从1开始)
per_page : 每页显示的数量
prev_num : 前一页页码数
next_num :后一页页码数
query :返回 创建这个Pagination对象的查询对象
pages : 一共有多少页
total :查询返回的一共有几条记录
iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2)
下面放上此次测试的一些用例。大部分时候不用看下面这些。注意all是关键字,我这里随便用了,平时不要轻易使用all当对象名。
all=User.query.paginate(page=1,per_page=3)
all_next=all.next(error_out=False)
print(all_next.page)
print(all.page)
print(all.has_next)
print(all.has_prev)
all=all.items
print(all)