数据库操作

现在我们创建了模型,生成了数据库和表,下面来学习常用的数据库操作,数据库操作主要是CRUD,即Create(创建)、Read(读取/查询)、Update(更新)和Delete(删除)。

SQLAlchemy使用数据库会话来管理数据库操作,这里的数据库会话也称为事务(transaction)。 Flask-SQLAlchemy自动帮我们创建会话,可以通过db.session属性获取。

数据库中的会话代表一个临时存储区,你对数据库做出的改动都会存放在这里。你可以调用add()方法将新创建的对象添加到数据库会话中,或是对会话中的对象进行更新。只有当你对数据库会话对象调用commit()方法时,改动才会提交到数据库,这确保了数据提交的一致性。另外,数据库会话也支持回滚操作。当你对会话调用rollback()方法时,添加到会话中且未提交的改动都将被撤销。

CRUD

下面我们在python shell中操作CRUD操作。默认情况下,Flask-SQLALchemy(>=2.3.0版本)会自动为模型类生成一个__repr__()方法。当在python shell中调用模型类的对象时,__repr__()方法会返回一条类似”<模型类名主键值>”的字符串,比如<Note 2>。下面示例中,模型类都重新定义了__repr__()方法,返回一些更有用的信息,比如:

class Note(db.Model):
id = db.Column(db.Integer, primary_key=True)
db.Column()
body = db.Column(db.Text)
def __repr__(self):
# %r是用repr()方法处理对象,返回类型本身,而不进行类型转化
return '<Note %r>' % self.body

在实际开发中,这并不是必须的。

Create

添加一条新纪录到数据库分三步:

1)  创建python对象(实例化模型类)作为一条记录

2)  添加新创建的记录到数据库会话。

3)  提交数据库会话

下面的示例向数据库中添加了三条留言:

>>> from app import db, Note
>>> note1=Note(body='remember Sam Xia')
>>> note2 = Note(body='Rose')
>>> note3 = Note(body = 'I AM HERE TO TRUW BUBLEGUM AND KIK ASS, AND NOW I AM ALL OUT OF BUBLEGUM~')
>>> db.session.add(note1)
>>> db.session.add(note2)
>>> db.session.add(note3)
>>> db.session.commit()

在这个例子中,首先从app模块导入db对象和Note类,然后分别创建三个Note实例表示三条记录,使用关键字参数传入字段数据。我们的Note类继承自db.Model基类,db.Model基类会为Note类提供一个构造函数,接收匹配类属性名称的参数值,并赋值给对应的类属性,所以我们不需要自己在Note类中定义构造方法。接着我们调用add()方法把这三个Note对象添加到会话对象db.session中,最后调用commit()方法提交会话。

除了依次调用add()方法添加多个记录,也可以使用add_all()依次添加包含所有记录对象的列表。

我们在创建模型类实例的时候并没有定义id字段的数据,这是因为主键由SQLAlchemy管理。模型类对象创建后作为临时对象(transient),当你提交数据库会话后,模型类对象才会转换为数据库记录写入数据库中,这时模型类对象会自动获取id值:

>>> note2.id

3

Flask-SQLAlchemy提供了一个SQLALCHEMY_COMMIT_ON_TEARDOWN配置,将其设为True可以设置自动调用commit()方法提交数据库会话。因为存在潜在的Bug,目前不建议使用。

可以使用db.session.commit()方法的方式提交数据库会话。

Read

如何从数据库取回数据呢,使用模型类提供的query属性附加调用各种过滤方法及查询方法可以完成这个任务。

一般来说,一个完整的查询遵循下面的模式:

<模型类>.query.<过滤方法>.<查询方法>

从某个模型类触发,通过在query属性对应的Query对象上附加的过滤方法和查询函数对模型类对应的表中的记录进行各种筛选和调整,最终返回包含对应数据库记录数据的模型类实例,对返回的实例调用属性即可获取对应的字段数据。

SQLAlchemy提供了许多查询方法用来获取记录,如下表:

表中的first_or_404()、get_or_404()以及paginate()方法是Flask-SQLAlchemy附加的查询方法。

下面是对Note类进行查询的几个例子。all()返回所有记录:

>>> Note.query.all()
[<Note u'Hello~'>, <Note u'remember Sam Xia'>, <Note u'Rose'>, <Note u'I AM HERE TO TRUW BUBLEGUM AND KIK ASS, AND NOW I AM ALL OUT OF BUBLEGUM~'>]
first()返回第一条记录:
>>> note1 = Note.query.first()
>>> note1
<Note u'Hello~'>
get()返回指定主键值(id字段)的记录:
>>> note2=Note.query.get(2)
>>> note2
<Note u'remember Sam Xia'>
>>> note2.body
u'remember Sam Xia'
count()返回记录的数量:
>>> Note.query.count()
4

SQLAlchemy还提供了许多过滤方法,使用这些过滤方法可以获取更精确的查询,比如获取指定字段值的记录。对模型类的query属性存储的query对象调用过滤方法将返回一个更精确的query对象(简称为查询对象)。因为每个过滤方法都会返回新的查询对象,所以过滤器可以叠加使用。在查询对象上调用前面说的查询方法,即可获得一个包含过滤后的记录的列表。常用的查询过滤方法如下所示:

filter()方法

filter()方法是最基础的查询方法。它使用指定的规则来过滤记录,下面的示例在数据库里找出了body字段值为”Rose”的记录:

>>> Note.query.filter(Note.body=='Rose').first()
<Note u'Rose'>

直接打印查询对象或将其转换为字符串可以查看对应当前SQL语句:

>>> print  Note.query.filter_by(body='Rose')
SELECT note.id AS note_id, note.body AS note_body
FROM note
WHERE note.body = ?

在filter()方法中传入表达式时,除了”==”以及表示不等于的”!=”,其他常用的查询操作符以及使用示例如下所示:

like:
>>> Note.query.filter(Note.body.like('%Sam%')).first()
<Note u'remember Sam Xia'>
in:
>>> Note.query.filter(Note.body.in_(['Rose','Sam'])).first()
<Note u'Rose'>
not in:
>>> Note.query.filter(~Note.body.in_(['foo'])).all()
[<Note u'Hello~'>, <Note u'remember Sam Xia'>, <Note u'Rose'>, <Note u'I AM HERE TO TRUW BUBLEGUM AND KIK ASS, AND NOW I AM ALL OUT OF BUBLEGUM~'>]
and:

使用and_()

>>>from sqlalchemy import and_
>>> Note.query.filter(and_(Note.body == 'Rose', Note.id == 3)).all()
[<Note u'Rose'>]

或者再filter()中加入多个表达式,使用逗号分隔

>>> Note.query.filter(Note.body == 'Rose', Note.id == 3).all()
[<Note u'Rose'>]

或叠加调用多个filter()/filter_by()方法

filter()中的等号是两个

>>> Note.query.filter(Note.body == 'Rose').filter(Note.id == 3).all()
[<Note u'Rose'>]

注意filter_by()中的等号是一个

>>> Note.query.filter_by(body='Rose').filter_by(id=3).all()
[<Note u'Rose'>]
or:
>>> Note.query.filter(or_(Note.body == 'Rose', Note.id == 2)).all()
[<Note u'remember Sam Xia'>, <Note u'Rose'>]

和filter()方法相比,filter_by()方法更易于使用。在filter_by()方法中,可以使用关键字表达式来指定过滤规则。更方便的是,可以在这个过滤器中直接使用字段名称。下面的例使用filter_by()过滤器完成了同样的任务:

>>> Note.query.filter_by(body = 'Rose').all()
[<Note u'Rose'>]
update

更新一条记录分拣单,直接赋值给模型类的字段属性就可以改变字段值,然后调用gcommit()方法提交会话即可,例如:

>>> note = Note.query.get(2)
>>> note.body
u'remember Sam Xia'
>>> note.body = 'Life is a dream'
>>> db.session.commit()
>>> note.body
u'Life is a dream'

只有要插入新的记录或要将现有的记录添加到会话中时才需要使用add()方法,单纯要更新现有的记录时只需要直接为属性赋新值,然后提交会话。

delete

删除记录和添加记录相似,不过要把add()方法换成delete()方法,最后都要调用commit()方法提交记录。

例如删除id(主键)为2的记录:

>>> note = Note.query.get(1)
>>> db.session.delete(note)
>>> db.session.commit()

flask 数据库操作(增删改查)的更多相关文章

  1. Yii数据库操作增删改查-[增加\查询\更新\删除 AR模式]

    在Yii的开发中常常需要去使用Yii的增删改查方法,这些方法又可以多次变化和组合,带来全方位的实现对数据库的处理,下面对这些方法做一些简单的整理和梳理,有遗漏或是BUG,敬请指出.灰常感谢!!! 一. ...

  2. Django数据库操作(增删改查)

    Django数据库操作(增删改查) 创建数据库中的一个表 class Business(models.Model): #自动创建ID列 caption = models.CharField(max_l ...

  3. Android下数据库操作——增删改查

    Android下数据库第一种方式增删改查     1.创建一个帮助类的对象,调用getReadableDatabase方法,返回一个SqliteDatebase对象     2.使用SqliteDat ...

  4. spring框架学习之--数据库操作增删改查

    基于spring的NamedParameterJdbcTemplate操作数据库 首先在 resources 文件夹下添加数据库配置文件jdbc.properties 配置常用的数据库信息 consu ...

  5. SpringBoot 数据库操作 增删改查

    1.pom添加依赖 <!--数据库相关配置--> <dependency> <groupId>org.springframework.boot</groupI ...

  6. Yii2.0数据库操作增删改查详解

    1.简单查询: one(): 根据查询结果返回查询的第一条记录. all(): 根据查询结果返回所有记录. count(): 返回记录的数量. sum(): 返回指定列的总数. average():  ...

  7. django数据库操作-增删改查-多对多关系以及一对多(外键)关系

    一.一对多(外键) 例子:一个作者对应多本书,一本书只有一个作者 model代码: class Person(models.Model); name = models.CharField('作者姓名' ...

  8. 转: django数据库操作-增删改查-多对多关系以及一对多(外键)关系

    原文链接:http://blog.csdn.net/u010271717/article/details/22044415 一.一对多(外键) 例子:一个作者对应多本书,一本书只有一个作者 model ...

  9. 使用JDBC连接MySQL数据库操作增删改查

    目录 1.首先这个Myeclipse的包名以及一些实现的类(这样子写是我的习惯) 2.接下来我们创建数据库(MySQL) 3.在数据库里面添加数据 4.首先是BaseDao,这个是重中之重,注意那个数 ...

  10. 通过Loadruner对mysql数据库进行增删改查

    操作mysql数据库,是在实现mysql数据源配置的基础上操作,可先阅读:loadrunner参数化使用mysql数据源失败解决方法 写之前先理一下,数据库访问流程:打开数据库  --> 数据库 ...

随机推荐

  1. 深入理解Java虚拟机笔记

    1. Java虚拟机所管理的内存 2. 对象创建过程 3. GC收集 4. HotSpot算法的实现 5. 垃圾收集器 6. 对象分配内存与回收细节 7. 类文件结构 8. 虚拟机类加载机制 9.类加 ...

  2. Docker 引擎(三)

    Docker 引擎是一个包含以下主要组件的客户端服务器应用程序. 一种服务器,它是一种称为守护进程并且长时间运行的程序. REST API用于指定程序可以用来与守护进程通信的接口,并指示它做什么. 一 ...

  3. 第二节:Linux下检出项目和提交项目

    1.在linux下获取项目: 2.在linux中提交项目: 这时候我们在光标处添加注释,然后保存退出. 再查看下状态: 接下来问题来了: 解决办法: vim .git/config 修改:[remot ...

  4. 【托业】【全真题库】TEST01-03-阅读题

    [托业][全真题库]TEST01-03-阅读题

  5. 一个ajax请求,接收json数据

    <a id="inviterDel" onclick="delInviter(${item.inviterAddId})">删除</a> ...

  6. 自定义PopView

    改代码是参考一个Demo直接改的,代码中有一些漏洞,如果发现其他的问题,可以下方直接留言 .h文件 #import <UIKit/UIKit.h> typedef void(^Popove ...

  7. idea-常用插件-nginx

    1.mac上nginx安装 brew search nginx brew install nginx 当然也可以编译安装 安装完以后,可以在终端输出的信息里看到一些配置路径: /usr/local/e ...

  8. UltraISO 9.7.0.3476中文完美破解安装版

    https://cn.ultraiso.net/uiso9_cn.exe 简体中文版专用:        注册名:Guanjiu 注册码:A06C-83A7-701D-6CFC 多国语言版专用: 注册 ...

  9. 实现并发join的方法

    import threadingimport time def music(): print("begin to listen %s" %time.ctime()) time.sl ...

  10. linux配置基本业务

    1.安装一些必备软件 yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlite-devel ...