Flask 实战:32、ORM 魔法

本贴最后更新于 2018 天前,其中的信息可能已经渤澥桑田

在 Web 应用里使用原生 SQL 语句操作数据库主要存在下面两类问题:

  • 手动编写 SQL 语句比较乏味,而且视图函数中加入太多 SQL 语句会降低代码的易读性。另外还会容易出现安全问题,比如 SQL 注入。

  • 常见的开发模式是在开发时使用简单的 SQLite,而在部署时切换到 MySQL 等更健壮的 DBMS。但是对于不同的 DBMS,我们需要使用不同的 Python 接口库,这让 DBMS 的切换变得不太容易。

注意
尽管使用 ORM 可以避免 SQL 注入问题,但你仍然需要对传入的查询参数进行验证。另外,在执行原生 SQL 语句时也要注意避免使用字符串拼接或字符串格式化的方式传入参数。

使用 ORM 可以很大程度上解决这些问题。它会自动帮你处理查询参数的转义,尽可能地避免 SQL 注入的发生。另外,它为不同的 DBMS 提供统一的接口,让切换工作变得非常简单。ORM 扮演翻译的角色,能够将我们的 Python 语言转换为 DBMS 能够读懂的 SQL 指令,让我们能够使用 Python 来操控数据库。

附注
尽管 ORM 非常方便,但如果你对 SQL 相当熟悉,那么自己编写 SQL 代码可以获得更大的灵活性和性能优势。就像是使用 IDE 一样,ORM 对初学者来说非常方便,但进阶以后你也许会想要自己掌控一切。

ORM 把底层的 SQL 数据实体转化成高层的 Python 对象,这样一来,你甚至不需要了解 SQL,只需要通过 Python 代码即可完成数据库操作,ORM 主要实现了三层映射关系:

  • 表 →Python 类。

  • 字段(列)→ 类属性。

  • 记录(行)→ 类实例。

比如,我们要创建一个 contacts 表来存储留言,其中包含用户名称和电话号码两个字段。在 SQL 中,下面的代码用来创建这个表:

CREATE TABLE contacts( name varchar(100) NOT NULL, phone_number varchar(32), );

如果使用 ORM,我们可以使用类似下面的 Python 类来定义这个表:

from foo_orm import Model, Column, String class Contact(Model): __tablename__ = 'contacts' name = Column(String(100), nullable=False) phone_number = Column(String(32))

要向表中插入一条记录,需要使用下面的 SQL 语句:

INSERT INTO contacts(name, phone_number) VALUES('Grey Li', '12345678');

使用 ORM 则只需要创建一个 Contact 类的实例,传入对应的参数表示各个列的数据即可。下面的代码和使用上面的 SQL 语句效果相同:

contact = Contact(name='Grey Li', phone_number='12345678')

除了便于使用,ORM 还有下面这些优点:

  • 灵活性好。你既能使用高层对象来操作数据库,又支持执行原生 SQL 语句。

  • 提升效率。从高层对象转换成原生 SQL 会牺牲一些性能,但这微不足道的性能牺牲换取的是巨大的效率提升。

  • 可移植性好。ORM 通常支持多种 DBMS,包括 MySQL、PostgreSQL、Oracle、SQLite 等。你可以随意更换 DBMS,只需要稍微改动少量配置。

使用 Python 实现的 ORM 有 SQLAlchemy、Peewee、PonyORM 等。其中 SQLAlchemy 是 Python 社区使用最广泛的 ORM 之一,我们将介绍如何在 Flask 程序中使用它。SQL-Alchemy,直译过来就是 SQL 炼金术,下一节我们会见识到 SQLAlchemy 的神奇力量。

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Wide

    Wide 是一款基于 Web 的 Go 语言 IDE。通过浏览器就可以进行 Go 开发,并有代码自动完成、查看表达式、编译反馈、Lint、实时结果输出等功能。

    欢迎访问我们运维的实例: https://wide.b3log.org

    30 引用 • 218 回帖 • 643 关注
  • ZeroNet

    ZeroNet 是一个基于比特币加密技术和 BT 网络技术的去中心化的、开放开源的网络和交流系统。

    1 引用 • 21 回帖 • 640 关注
  • abitmean

    有点意思就行了

    30 关注
  • 自由行
    1 关注
  • V2EX

    V2EX 是创意工作者们的社区。这里目前汇聚了超过 400,000 名主要来自互联网行业、游戏行业和媒体行业的创意工作者。V2EX 希望能够成为创意工作者们的生活和事业的一部分。

    16 引用 • 236 回帖 • 269 关注
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    88 引用 • 1235 回帖 • 416 关注
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    946 引用 • 1460 回帖 • 1 关注
  • 叶归
    5 引用 • 16 回帖 • 10 关注
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖 • 1 关注
  • SOHO

    为成为自由职业者在家办公而努力吧!

    7 引用 • 55 回帖 • 4 关注
  • 书籍

    宋真宗赵恒曾经说过:“书中自有黄金屋,书中自有颜如玉。”

    77 引用 • 389 回帖
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3194 引用 • 8214 回帖
  • 电影

    这是一个不能说的秘密。

    122 引用 • 608 回帖
  • IPFS

    IPFS(InterPlanetary File System,星际文件系统)是永久的、去中心化保存和共享文件的方法,这是一种内容可寻址、版本化、点对点超媒体的分布式协议。请浏览 IPFS 入门笔记了解更多细节。

    21 引用 • 245 回帖 • 232 关注
  • Gzip

    gzip (GNU zip)是 GNU 自由软件的文件压缩程序。我们在 Linux 中经常会用到后缀为 .gz 的文件,它们就是 Gzip 格式的。现今已经成为互联网上使用非常普遍的一种数据压缩格式,或者说一种文件格式。

    9 引用 • 12 回帖 • 168 关注
  • ReactiveX

    ReactiveX 是一个专注于异步编程与控制可观察数据(或者事件)流的 API。它组合了观察者模式,迭代器模式和函数式编程的优秀思想。

    1 引用 • 2 回帖 • 175 关注
  • Solidity

    Solidity 是一种智能合约高级语言,运行在 [以太坊] 虚拟机(EVM)之上。它的语法接近于 JavaScript,是一种面向对象的语言。

    3 引用 • 18 回帖 • 430 关注
  • OkHttp

    OkHttp 是一款 HTTP & HTTP/2 客户端库,专为 Android 和 Java 应用打造。

    16 引用 • 6 回帖 • 83 关注
  • etcd

    etcd 是一个分布式、高可用的 key-value 数据存储,专门用于在分布式系统中保存关键数据。

    6 引用 • 26 回帖 • 544 关注
  • LaTeX

    LaTeX(音译“拉泰赫”)是一种基于 ΤΕΧ 的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在 20 世纪 80 年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由 TeX 所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

    12 引用 • 54 回帖 • 17 关注
  • Node.js

    Node.js 是一个基于 Chrome JavaScript 运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞 I/O 模型而得以轻量和高效。

    139 引用 • 269 回帖 • 1 关注
  • 招聘

    哪里都缺人,哪里都不缺人。

    189 引用 • 1057 回帖
  • Google

    Google(Google Inc.,NASDAQ:GOOG)是一家美国上市公司(公有股份公司),于 1998 年 9 月 7 日以私有股份公司的形式创立,设计并管理一个互联网搜索引擎。Google 公司的总部称作“Googleplex”,它位于加利福尼亚山景城。Google 目前被公认为是全球规模最大的搜索引擎,它提供了简单易用的免费服务。不作恶(Don't be evil)是谷歌公司的一项非正式的公司口号。

    49 引用 • 192 回帖 • 1 关注
  • JavaScript

    JavaScript 一种动态类型、弱类型、基于原型的直译式脚本语言,内置支持类型。它的解释器被称为 JavaScript 引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在 HTML 网页上使用,用来给 HTML 网页增加动态功能。

    729 引用 • 1278 回帖
  • Flume

    Flume 是一套分布式的、可靠的,可用于有效地收集、聚合和搬运大量日志数据的服务架构。

    9 引用 • 6 回帖 • 651 关注
  • 酷鸟浏览器

    安全 · 稳定 · 快速
    为跨境从业人员提供专业的跨境浏览器

    3 引用 • 59 回帖 • 46 关注
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    34 引用 • 467 回帖 • 759 关注