爱上 SQLAlchemy 的 10 个理由(转)

原文:http://python.jobbole.com/82453/

本文由 伯乐在线 - Namco 翻译,唐尤华 校稿。未经许可,禁止转载!
英文出处:Paul Johnston。欢迎加入翻译组

最近,我见到了很多针对 ORM 的抨击,但是我觉得有些批评是莫须有的。我本人就是 SQLAlchemy 的忠实拥趸。在我的项目里很多地方都用到了 SQLAlchemy,我也为 SQLAlchemy 项目贡献了一些代码。这篇文章里我会阐述你应当爱上 SQLAlchemy 的10个理由。说实话,除了 SQLAlchemy 以外还有很多优秀的 ORM,我所阐述的大部分理由同样适用于它们但是 SQLAlchemy 是我的最爱。

1、用应用程序代码定义数据库模式

SQLAlchemy 允许你使用 Python 代码来定义数据库模式(schema)。下面是一个电子商务网站的例子,一个订单就代表一条记录。

Python

1

2

3

4

5

class OrderItem(Base):

id = Column(Integer, primary_key=True)

order = many_to_one(‘Order‘)

product = many_to_one(‘Product‘)

quantity = Column(Integer)

定义数据库模式的 Python 代码在 SQLAlchemy 中叫做模型(model)。因为这些模型都是用 Python 的类实现的,所以你可以添加自己的类方法。这样可以把相关功能放在一起方便维护。

Python

1

2

3

4

5

class Order(Base):

...

def update_stock(self):

for item in self.items:

item.product.stock -= item.quantity

上面这个例子说明了在 SQLAlchemy 中数据库的模式也可以通过版本控制来维护。所以使用SQLAlchemy 的同时,你也可以享受到版本控制的诸多便利:比如版本追踪、标签、追溯(blame)等等。

2、自动同步模型到数据库模式

Alembic 是 SQLAlchemy 的一个数据库管理插件。当你修改模型的时候,Alembic 可以自动更新数据库模式。使用 Alembic 来做一些添加表或者列的小改动是非常便捷快速的。

Python

1

2

3

4

$ alembic upgrade head

INFO  [alembic.context] Context class PostgresqlContext.

INFO  [alembic.context] Will assume transactional DDL.

INFO  [alembic.context] Running upgrade None -> 1975ea83b712

尽管在开发环境中自动同步非常方便,但是大多数人还是想在生产环境中采用更稳妥一些的方式。这一点 Alembic 也想到了,它可以自动生成修改的脚本,数据库管理员可以在检视脚本之后再应用到生产环境的数据库上。

3、Pythonic 的代码风格让你的代码更易读

SQLAlchemy 使用更 Pythonic 的方式表示数据库关系,这对于阅读和编写代码来说是非常方便的。我们来看下面这个例子,这个例子可以打印出在一个订单中的所有产品。

Python

1

2

for item in order.items:

print(item.product.name, item.quantity)

代码非常的简单易读,但是打通了两个数据库,执行了 JOIN 连接查询。order.items 是一对多的关系,SQLAlchemy 会自动加载 OrderItem 中和这个订单相关的对象。item.product 则储存的是多对一的关系,SQLAlchemy 会自动加载对应的产品。

SQLAlchemy 也可以运用类。如果应用修改了一个有映射的字段,对象会自动请求写入数据库。这个功能使编写应用逻辑的时候没有了后顾之忧。

4、用 Python 构建查询语句

类似用主键获取对象这种简单查询只需要很少的代码:

Python

1

order = session.query(Order).get(order_id)

使用 Python 的查询语法,我们可以实现更复杂的查询。比如下面的例子,我要查找两天以前的有效订单:

Python

1

2

overdue_orders = session.query(Order).filter(Order.status == ‘active‘

&& Order.time < datetime.now() - timedelta(days=2))

SQLAlchemy 的语法可以让你把 SQL 语句和 Python 的变量结合起来,并且可以杜绝 SQL 注入攻击。SQLAlchemy 会在内部重载各种比较运算符,然后将它们转换成 SQL 语句。

当你执行一条非常复杂的查询时,使用 SQLAlchemy 语法来定义查询也是可以的。但是我认为 SQLAlchemy 可以胜任的查询复杂程度是有限的,某些时候直接写 SQL 语句可能更容易些。在这种情况下,你可以定义数据库视图来完成复杂查询,SQLAlchemy 可以把视图映射到 Python 对象。

5、与 Web 框架的无缝集成

有些框架默认支持SQLALchemy ,比如说 Pyramid。对于其他 web 框架,你需要安装一个集成库来支持 SQLAlchemy,比如说用于 Flask 的 Flask-SQLAlchemy 或者用于 Django 的 aldjemy。

SQLAlchemy 会维持一个连接池,为每一个 web 请求提供一个可用的数据库连接。那些支持库可以处理常见异常,提高应用的健壮性,让应用在某些异常情况下不至于崩溃,比如运行时重启数据库这样的操作。

每一个请求都会用事务包裹起来,如果请求成功就提交事务,否则就回滚。这种设计使得外部方法能够正确地与数据库交互,而不需要关心具体的数据库处理代码。

6、预先加载提高性能

大部分 ORM 都使用的是延迟加载策略。在第一次调用关系时,一次 SQL 查询会执行,加载数据。像上面的例子,order.items 的调用实际上执行了一次 SQL 查询,之后的每次使用 item.product 都会发起另外的查询。因为 item.product 是在一个循环中调用的,所以会生成大量的 SQL 查询,导致性能降低。这种情况叫做“n+1 选择问题”。

SQLAlchemy 针对上述问题有一个解决方案:预先加载(eager loading)。当我们第一次加载 Order 这个对象时,我们可以通知 SQLAlchemy 我们会使用那些关系,然后 SQLAlchemy 就能在一次查询中加载所有数据,语法如下所示:

Python

1

session.query(Order).options(joinedload_all(‘items.product‘)).get(order_id)

7、透明的多态支持

像 Python 这样的面向对象语言是鼓励使用多态的。如果有一个 Person 的基类,我们就可以基于 Person 来创建子类,比如 增加了新字段的Employee 或者 Customer 类。但是传统的 SQL 数据库不支持多态,所以 ORM 想要支持多态也是有心无力。

但是 SQLAlchemy 在 SQL 中完美地模拟了多态。我们在 Python 代码中可以非常自然地使用多态,数据库中的数据也可以通过 SQL 便捷地获取。在应用代码中我们可以轻松地使用多态类,而不需要关心它们究竟是怎么存储的。

8、兼容已有数据库

一些 ORM 要求你的数据库结构满足既定条件,强制每张表都有单一主键列,甚至主键名称必须是 “id”。如果你从头建立一个数据库,这些限制并不是问题。但是如果你想用以前的数据库,这些限制条件会阻止你访问那些不满足条件的表。

SQLAlchemy 不会假定你的数据库结构,所以可以完美支持以前的数据库。还有一个叫做 sqlacodegen 的工具可以根据已有的数据库生成 SQLAlchemy 模型。SQLAlchemy 使得你可以通过简单的 Python 脚本和以前的数据库进行交互。

9、提供许多钩子函数让你自定义库

SQLAlchemy 拥有清晰的分层架构。几乎任何 SQLAlchemy 库都可以被重写以满足特定需求。

当在有多个使用者的云应用上工作的时候,我发现了一个非常有用的功能。比如说应用中大多数查询都包含了过滤条件,只返回当前使用者的结果。就像下面这个例子:

Python

1

products = session.query(Product).filter(Product.merchant == current_user.merchant).all()

但是我发现,如果一不小心忘记加过滤条件的话,可能让某个用户可以看到其他经销商的信息,而这是不允许的。谨慎起见,我们可以创建一个自定义的 SQLAlchemy 的 session 工厂函数,可以在会话中自动给所有查询应用过滤条件。虽然只是这么一点小小的控制代码,却可以让你的应用安全系数更高。

10、完善的文档

有些开源项目的文档的确是漏洞百出,但是 SQLAlchemy 不是这样。SQLAlchemy 的文档非常详尽,并且还有从简单例子到高级特性的学习指南,以及全面的 API 参考文档。这对于开发人员学习和使用 SQLAlchemy 是非常有帮助的。

时间: 2024-10-19 07:53:08

爱上 SQLAlchemy 的 10 个理由(转)的相关文章

爱上 Java 的10 大理由,Python 弱爆了!

Java和JVM已经存在了很长一段时间了,基于这个事实,一些程序员开始将很多事情视为理所当然.今天我们就来说一说"Java之所以能够成为并将继续是软件项目领先平台"的十大理由. 1.高性能JVM Java最初的开发目的"一次编写到处运行",并由虚拟机提供运行平台.点击这里查看JVM内存模型详解.没有JVM,Java就必须遵循Ruby和Python的步伐--在痛苦中进一步提高其便携性.随着物联网的出现,一个强大的虚拟机变得越来越重要. 2.核心API 最让人喜欢的就是

高校应该使用 Drupal 的10大理由

使用 Drupal 已经成为全球顶尖高校中的一种潮流,它已经被全球数以百计的院校选择并应用,无论是哈佛.斯坦福.杜克.布朗.罗格斯.剑桥.耶鲁还是其它众多知名高校,都已经选择 Drupal 作为它们理想的内容管理框架,因为它不仅能高校们现在的需求,更能够容纳关于未来的无限可能性. 简单来讲,Drupal 已经被证实它足以满足高校中对于各种网站的需求.如果你有兴趣,可以了解一下有关 Drupal 适用于高校的10大理由. (译注:因为国内外环境差异较大,本文所述的10大理由也并非完全适用于国内高校

我痛恨 Git 的 10 个理由(转)

Git 是一个源代码版本控制系统,正在迅速成为开源项目的标准.它有一个强大的分布式模型,允许高级用户用分支来处理各种棘手的问题和改写历史记录.但是,要学习 Git 是需要付出更多的努力,让人不爽的命令行接口以及 Git 是如此的忽视它的使用者. 下面是我为什么如此痛恨 Git 的 10 个理由: 1. 复杂的信息模型 Git 的信息模型是很复杂的,而且你必须对他们都很了解.在这个方面上你看看 Subversion:有文件.工作目录.资源库.版本.分支和标签.你需要了解的就是这些东西,实际上,分支

喜爱Sahi的10个理由

使用Sahi作为web自动化测试工具一年以来,深深喜欢上了这个小巧简单却功能强大的工具.下面列举喜爱Sahi的10个理由. 工具与语言本身 1. 容易上手 个人体验,Sahi学习起来要比QTP.Selenium更简单.Sahi网站有一个长约5分钟的视频(http://sahi.co.in/static/sahi_tutorial.html)非常值得一看.看完视频,下载完Sahi,一天之内你应该就可以开发出自己的第一个Sahi脚本. 2.2. 对ExtJS支持不错 QTP能支持的对于动态ID的支持

爱上Java和JVM的10大理由

1.高性能JVM Java最初的开发目的“一次编写到处运行”,并由虚拟机提供运行平台.没有JVM,Java就必须遵循Ruby和Python的步伐——在痛苦中进一步提高其便携性.随着物联网的出现,一个强大的虚拟机变得越来越重要. 2.核心API 最让人喜欢的就是Java核心API——从它诞生之后就可以完全向后兼容,这样我们就可以开始写更多的Java应用.虽然有无数额外的库和JVM语言可以提供简洁的语言水平,以获取多种核心API功能,但其中大部分实际上是依赖于Java核心API的支配.虽然也有其他语

【扣丁学堂】10个理由让你继续干IT

每日一课:扣丁学堂 作为iOS与Android培训领头羊的扣丁学堂,对iOS与Android的研究都是走在互联网发展的潮流最前沿,把最新最好的技术教导给学生. 在课程体系外,还有很多有趣的IT资讯分享给大家: 我曾在"正规"IT这个行当中几进几出.已经从挫折这所学校里面了解到了许多坚守下来的理由.说实话,或多或少地,上述每一条我都有做不到的地方.当你真正了解了干IT的基本理由之后,你就会知道,是IT而不是别的职业能够满足技术头脑的更多需求. 1.钱,钱,钱 对,我们努力工作就是为了赚钱

使用消息队列的 10 个理由

We’ve been working with, building, and evangelising message queues for the last year, and it’s no secret that we think they’re awesome. We believe message queues are a vital component to any architecture or application, and here are ten reasons why:

使用FreeMarker替换JSP的10个理由

你还在使用 Java 服务器页面(俗称JSP)吗?我曾经也是,但是几年前我抛弃了它们,并且再也没有用过JSP了.JSP 是个很好的概念,但是它却剥夺了 web 开发的乐趣. 对我而言,这些都是小事,比如无法在页面模板上使用单独的文件header.jsp 和 footer.jsp,不能调用表达式语言的方法,在运行时无法合并,重新排列页面的各个部分.所以我转而使用 FreeMarker 模板.FreeMarker 已经存在一段时间了,如果你最近没有关注过 FreeMarker 的话,那这有些建议给你

足以说服你跟程序猿约会的10个理由

1. 我们非常忠诚 程序猿与生俱来忠诚的品质. 假设一个人能忠诚于硬件,操作系统等枯燥的玩意儿的话,你能够想象当他遇到还有一半的时候,会是怎样的忠诚. 2. 我们非常细心 看看程序猿.极客们是对待他们心爱的收藏,比如各种小部件,CPU等等,你就能够明确当他爱上你以后,他会怎样细心的对待你. 3. 我们不创造问题,我们解决这个问题 我们的使命就是解决这个问题. 我们一直在寻找问题.并解决这个问题.我老婆对这一点就非常惬意,无论什么时候仅仅要有问题出现,我就会尽全力去解决它. 4. 我们喜欢聆听 我