美文网首页
(四) flask的models

(四) flask的models

作者: fanhang64 | 来源:发表于2018-03-28 19:39 被阅读79次

一. 在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))

相关文章

网友评论

      本文标题:(四) flask的models

      本文链接:https://www.haomeiwen.com/subject/nzvucftx.html