天天看点

用 Flask 来写个轻博客 (5) — (M)VC_SQLAlchemy 的 CRUD 详解目录前文列表扩展阅读SQLAlchemy 的 CRUDCreate 增添数据Retrieve 读取数据Update 更新数据Delete 删除数据

<a href="#%E7%9B%AE%E5%BD%95">目录</a>

<a href="#%E5%89%8D%E6%96%87%E5%88%97%E8%A1%A8">前文列表</a>

<a href="#%E6%89%A9%E5%B1%95%E9%98%85%E8%AF%BB">扩展阅读</a>

<a href="#sqlalchemy-%E7%9A%84-crud">SQLAlchemy 的 CRUD</a>

<a href="#create-%E5%A2%9E%E6%B7%BB%E6%95%B0%E6%8D%AE">Create 增添数据</a>

<a href="#retrieve-%E8%AF%BB%E5%8F%96%E6%95%B0%E6%8D%AE">Retrieve 读取数据</a>

<a href="#%E9%99%90%E5%88%B6%E8%BF%94%E5%9B%9E%E8%AE%B0%E5%BD%95%E7%9A%84%E6%95%B0%E7%9B%AE">限制返回记录的数目</a>

<a href="#%E8%BF%94%E5%9B%9E%E8%AE%B0%E5%BD%95%E7%9A%84%E6%8E%92%E5%BA%8F">返回记录的排序</a>

<a href="#%E6%9F%A5%E8%AF%A2%E5%87%BD%E6%95%B0%E7%9A%84%E9%93%BE%E5%BC%8F%E8%B0%83%E7%94%A8">查询函数的链式调用</a>

<a href="#flask-sqlalchemy-%E7%9A%84%E4%B8%93%E6%9C%89%E5%88%86%E9%A1%B5%E5%87%BD%E6%95%B0-pagination">Flask-SQLAlchemy 的专有分页函数 pagination</a>

<a href="#query-%E7%9A%84%E8%BF%87%E6%BB%A4%E5%99%A8">Query 的过滤器</a>

<a href="#update-%E6%9B%B4%E6%96%B0%E6%95%B0%E6%8D%AE">Update 更新数据</a>

<a href="#delete-%E5%88%A0%E9%99%A4%E6%95%B0%E6%8D%AE">Delete 删除数据</a>

<a href="http://blog.csdn.net/jmilk/article/details/53150084">用 Flask 来写个轻博客 (1) — 创建项目</a>

<a href="http://blog.csdn.net/jmilk/article/details/53152158">用 Flask 来写个轻博客 (2) — Hello World!</a>

<a href="http://blog.csdn.net/jmilk/article/details/53153382">用 Flask 来写个轻博客 (3) — (M)VC_连接 MySQL 和 SQLAlchemy</a>

<a href="http://blog.csdn.net/jmilk/article/details/53184903">用 Flask 来写个轻博客 (4) — (M)VC_创建数据模型和表</a>

CRUD 提供了在 Web 应用程序中所需要的所有操作和检视数据的基础功能, 尤其在 REST 风格的应用中, CRUD 就能实现一切所需功能.

本篇博文主要记录 SQLAlchemy 实现 CRUD 的语句, 依然是在 manager shell 中完成:

为了让在 manager shell 中的执行效果更直观一些, 首先, 先对 User models 做一些修改:

为新建的 User models 添加一条记录的操作看起来跟 Git 的提交操作非常类似, 其包含的意义也大致相同, 是为了尽量减少不必要的 I/O 操作:

add: 把数据添加到会话对象中 (数据状态为待保存)

commit: 将会话对象中的数据提交 (数据被写入数据库中)

然后再查看一下数据库, 检验是否生效:

从这个例子可以看出, 一个 class User 的实例化对象就是一条包含了字段值的记录对象, 将该记录对象添加并提交到 session , 就会把记录对象的数据写入到数据库中.

把数据添加仅数据库表后, SQLAlchemy 可以通过 Model.query 方法对数据进行查询. <code>Model.query == db.session.query(Model)</code> 两种写法是等效的. 区别在于前者使用的是 flask_sqlalchemy.BaseQuery object, 后者使用的是 sqlalchemy.orm.query.Query object . 但两者本质上都是一个 Query 对象.

读取数据有两种情况:

读取一条数据: 需要指定唯一的过滤条件来获取, 一般会使用主键作为过滤条件.

读取多条数据: 指定任意条件作为过滤条件或者不过滤的获取全部数据

NOTE: 因为在 Flask 中的 SQLAlchemy 拥有 flask-sqlalchemy 和 sqlalchemy.orm 两种语法, 为了避免看花眼的情况, 以后的代码中只会使用通用性更强一些的 sqlalchemy.orm 的语法.

除了上述两种操作之外, 还有非常之多不同花样的数据读取方式, 读取数据是 4 种操作类型中最复杂多样的一中操作类型.

这个返回特征常与数据的分页功能结合使用.

SQLAlchemy 默认会根据主键的顺序来排序, 也是要显示的使用 order_by 函数来指定排序条件和排序的方式:

Query 对象提供了非常多且灵活的数据库操作抽象方法, 我们可以链式的去组合这些方法来达到希望的效果. 但需要注意的是, 删除操作的链式调用一定要谨慎而为.

可以使用 dir() 内置函数来查看一个 Query 对象提供的方法列表.

NOTE: 一条读取语句的链式操作都是一个 first() 或 all() 函数结束的. 它们会终止链式调用并返回结果.

pagination(): 是专门设计来实现分页功能的函数, 所以必须由 flask_sqlalchemy.BaseQuery object 来调用.

第一个参数表示查询返回第几页的内容

第二个参数表示每页显示的对象数量

paginate() 与 first()/all() 不同, 后者返回的是一个 models 对象或 models 对象列表, 而前者返回的是一个 pagination 对象. 而且 pagination 对象还包含了几个特有的属性:

在查询数据时, 可以根据一定的条件集合来获得过滤后的数据. SQLAlchemy 提供了过滤器 <code>query.filter_by()</code> 和 <code>query.filter()</code>, 过滤器接受的参数就是过滤条件, 有下面几种形式:

字段键值对, EG. <code>username='fanguiju'</code>

比较表达式, EG. <code>User.id &gt; 100</code>

逻辑函数, EG. <code>in_/not_/or_</code>

EXAMPLE:

可以将 <code>query.filter()</code> 内置的逻辑函数 <code>in_/not_/or_</code> 结合使用来实现更复杂的过滤.

如上述例子, 先定位到你希望更新的记录, 然后通过 Query 对象的 <code>update()</code> 传递要更新内容. 注意: 更新的内容必须是 Dict 数据类型.

需要注意的是: 就如使用原生 SQL 指令来更新记录一样, 如果没有指定要更新具体的哪一条记录的话, 会将该字段所在列的所有记录值一同更新, 所以切记使用过滤条件来定位到具体需要更新的记录.

而且 <code>update()</code> 会自动的添加 User 的实例化对象到 session 中, 所以直接 commit 就可以写入到数据库了.

将查询返回的 User 实例化对象进行 session 的 delete 操作, 就能够删除该对象所映射的记录数据了.