美文网首页
Flask-SQLAlchemy CRUD

Flask-SQLAlchemy CRUD

作者: Stone0823 | 来源:发表于2018-12-15 17:49 被阅读29次

    当我们习惯 Flask-SQLAlchemy 对数据库进行 CRUD 操作后,就很难再回到基于原生 SQL 的代码编写了。

    我们先来看 Read 操作。用实际的例子来说明用法,数据还是之前经常用到的 emp_master
    基于上一篇 Flask 工程的文件结构,在 models.py 中定义的 Class 如下:

    class EmpMaster(db.Model):
        emp_id = db.Column(db.Integer, primary_key=True)
        gender = db.Column(db.String(10), nullable=False)
        age = db.Column(db.Integer)
        email = db.Column(db.String(50))
        phone_nr = db.Column(db.String(20))
        education = db.Column(db.String(20))
        marital_stat = db.Column(db.String(20))
        nr_of_children = db.Column(db.Integer)
    
        def __repr__(self):
            return '<emp_master %r>' % 'id:{}'.format(self.emp_id)
    

    查询数据

    查询所有数据

    from app.models import db, EmpMaster
    
    print (EmpMaster.query.all())
    

    EmpMaster.query 得到的是 BaseQuery 对象的实例,对于 BaseQuery 类,SQLAlchemy 提供了一些查询方法用于获得你想要的查询对象,比如 all() 方法以 list (列表) 的形式返回所有的查询结果。

    根据主键查询数据

    get()get_or_404() 方法根据主键来查询数据。get() 方法返回 model 的实例,如果找不到,则返回 None;而 get_or_404() 则返回 Not found 的错误响应。

    EmpMaster.query.get(1001)       # 1001 是主键
    

    筛选/过滤数据

    筛选过滤数据通过 filter_by()filter() 方法。假设我们想查询所有女性雇员,可以这样做:

    emps = EmpMaster.query.filter_by(gender='Female').all()
    if len(emps) > 0:
        for emp in emps:
            print(emp.emp_id, emp.gender, emp.email, emp.education)
    else:
        print ('No data.')
    

    filter_by() 方法返回的是 BaseQuery 对象实例,参数是关键字表达式 (keyword expression),可以多个字段,多个字段之间为 and 关系。比如要查询所有女性,并且学历为 Bachelor 的员工:

    emps = EmpMaster.query.filter_by(gender='Female', education='Bachelor11').all()
    if len(emps) > 0:
        for emp in emps:
            print(emp.emp_id, emp.gender, emp.email, emp.education)
    else:
        print ('No data.')
    

    更为灵活的方式是通过 filter() 方法,与 filter_by() 方法不同的是,filter() 方法的参数是 SQL Expression。举几个例子来说明。

    查找所有 education 为 Bachelor 的员工:

    emps = EmpMaster.query.filter(EmpMaster.education == 'Bachelor').all()
    for emp in emps:
        print (emp)
    

    如果用 filter_by() 方法,是这样的:

    emps = EmpMaster.query.filter_by(education='Bachelor').all()
    

    看出区别来了吧。下表列示了常见条件的写法。

    条件 示例
    等于 query.filter(EmpMaster.education == 'Bachelor')
    不等于 query.filter(EmpMaster.education != 'Bachelor')
    LIKE query.filter(EmpMaster.email.like('s%'))
    IN query.filter(EmpMaster.education.in_(['Master', 'Bachelor']))
    NOT IN query.filter(~EmpMaster.education.in_(['Master', 'Bachelor']))
    IS NULL query.filter(EmpMaster.education == None)
    IS NOT NULL query.filter(EmpMaster.education != None)

    AND 条件:

    EmpMaster.query.filter(EmpMaster.gender=='Female', EmpMaster.education=='Bachelor')
    
    # 或者
    from sqlalchemy import and_
    emps = EmpMaster.query.filter(
        and_(EmpMaster.gender=='Female', EmpMaster.education=='Bachelor')).all()
    

    OR 条件

    from sqlalchemy import or_
    emps = EmpMaster.query.filter(
      or_(EmpMaster.marital_stat=='Single', EmpMaster.nr_of_children==0))
    

    Create

    SQLAlchemy 有一个 session 对象,代表临时存储区,数据的变动提交到 session 后,需要调用 commit() 将修改提交到数据库,或者 rollback() 撤销未提交的修改。

    from app.models import db, EmpMaster
    from app import create_app
    
    app = create_app()
    
    new_emp = EmpMaster(
        emp_id = 9001,
        gender = 'Female',
        age = 18,
        email = 'test@qq.com',
        phone_nr = '13800138000',
        education = 'Master',
        marital_stat = 'Single',
        nr_of_children = 0
    )
    
    db.session.add(new_emp)
    db.session.commit()
    

    可以使用 add_all() 方法批量创建记录:

    emp1 = EmpMaster(...)
    emp2 = EmpMaster(...)
    
    db.session.add_all([emp1, emp2])
    db.session.commit()
    

    Update

    Update 记录需要先定位到某记录,然后对需要的字段赋值后,然后调用 commit() 方法提交修改:

    emp = EmpMaster.query.get(9001)
    emp.email = 'e9001@qq.com'
    db.session.commit()
    

    Delete

    Delete 记录先定位到某记录,然后调用 delete() 方法发送删除指到 session,最后调用 commit() 将请求提交到数据库。

    emp = EmpMaster.query.get(9001)
    db.session.delete(emp)
    db.session.commit()
    

    相关文章

      网友评论

          本文标题:Flask-SQLAlchemy CRUD

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