21.1 介绍

21.1.1 持久存储

在任何的应用程序中,都需要持久存储。一般说来,有三种基本的存储机制:文件、关系型数据库或其他的一些变种,例如现有系统的API、ORM、文件管理器、电子表格、配置文件等。

在前面的章节中,我们研究了通过基于常规文件的Python和DBM接口来实现持久存储、比如*dbm、dbhas/bsddb文件、helve (pickle和DBM的结合)。这些接口都提供了类似字典的对象接口。本章的主题是如何在中大型项目中使用关系型数据库(对这些项目而言,那些接口力不从心)。

21.1.2 基本的数据库操作和SQL语言

在深入主题之前,下面先简单介绍一下基本的数据库概念和结构化查询语言(Structured QueryLanguage, SQL)。如果你有足够的经验,可以跳过,也可以通过阅读正文来复习一下。

1.底层存储

数据库的底层存储通常使用文件系统,它可以是普通操作系统文件、专用操作系统文件,甚至有可能是磁盘分区。

2.用户界面

大部分的数据库系统会提供一个命令行工具来执行SQL命令和查询,当然也有一些使用图形界面的漂漂亮亮的客户端程序来干同样的事。

3.数据库

关系型数据库管理系统通常通常都支持多个数据库,例如销售库、市场库、客户支持库等。如果你使用的关系数据库管理系统是基于服务器的,这些数据库就都在同一台服务器上(一些简单的关系型数据库没有服务器,如sqlite)。本章的例子中,MySQL是一种基于服务器的关系数据库管理系统(只要服务器在运行,它就一直在等待运行指令),SQLite和Gadfly则是另一种轻量型的基于文件的关系数据库(它们没有服务器)。

4.组件

你可以将数据库存储想像为一个表格,每行数据都有一个或多个字段对应着数据库中的列。每个表每个列及其数据类型的集合构成数据库结构的定义。数据库能够被创建,也可以被删除,表也一样。往数据库里增加一条记录称为插入(inserting),修改库中一条已有的记录则称为更新(updating).,删除表中已经有的数据行称为删除(deleting)。这些操作通常作为数据库操作命令来提交。从一个数据库中请求符合条件的数据称为查询(querying)。当你对一个数据库进行查询时,你可以一步取回所有符合条件的数据,也可以循环逐条取出每一行。有些数据库使用游标的概念来表示SQL命令、查询、取回结果集等。

  1. SQL

数据库命令和查询操作需要通过SQL语句来执行,不是所有的数据库都使用SQL,但所有主流的关系型数据库都使用SQL。下面是一些SQL命令的例子,绝大多数数据库被配置为大小写不敏感,除了数据库操作命令以外。被广为接受的书写SQL的基本风格是关键字大写。绝大多数命令行程序要求用一个分号来结束一条SQL语句。

(1)创建数据库

21.1 介绍 - 图1

第一行创建一个名为”test”的数据库,第二行将该数据库的权限赋给具体用户(或者全部用户),以便它们可以执行下面的数据库操作。

(2)选择要使用的数据库

USE test;

21.1 介绍 - 图2

如果在登录数据库时没有指定要使用那个数据库,这条简单的语句就可以指定你打算访问的数据库。

(3)删除数据库

21.1 介绍 - 图3

这条短短的语句具有极大的威力,它用来删除数据库(包括数据库中所有的表及表中的数据)。在输入完这条语句按下回车之前,好好想想你是否真的打算这么做。

(4)创建表

21.1 介绍 - 图4

这个语句用于创建表users,它有一个类型为字符串的列login和两个类型为整型的字段uid和prid。

(5)删除表

21.1 介绍 - 图5

这个简单的语句删除数据库中的一个表和它的所有数据。

(6)插入行

21.1 介绍 - 图6

INSERT语句用来向数据库中添加新的数据行。语句中必须指定要插入的表及该表中各个字段的值。上例中,表名是users,字符串’leanna’对应着login字段,311和1分别对应着uid和prid。

(7)更新行

21.1 介绍 - 图7

UPDATE语句用来改变数据库中的已有记录。使用SET关键字来指定你要修改的字段及新值,你可以指定条件来筛选出需要更新的记录。在第一个例子中,所有prid字段值为2的记录,其prid字段的值都变更为4。在第二个例子里,uid字段值为311的用户,其prid字段的新值被置为1。

(8)删除行

21.1 介绍 - 图8

DELETE FROM命令用来删除数据。必须指定你要删除的数据所在表名,如果未提供(可选的)筛选条件,就像第二个例子一样,表中所有的数据都会被删除。

现在你已经了解数据库的基本概念,有了这些基础,本章余下的部分学起来会更加容易。如果需要进一步了解数据库知识,市面上有数不清的数据库书籍可供选择。

21.1.3 数据库和Python

下面我们要详细了解Python数据库API。Python能够直接通过数据库接口,也可以通过ORM(不需要自己书写SQL)来访问关系数据库。

关于数据库原理、并发能力、视图、原子性、数据完整性、数据可恢复性、左连接、触发器、查询优化、事务支持及存储过程等主题,(市面上)有数不清的资源可供参考。本章不讨论这些主题,我们将从一个Python应用程序开始,了解在Python框架下如何将数据保存到数据库,如何将数据从数据库中取出来。之后你就可以决定哪种方式适用于你手头的项目。通过学习示例代码,你可以立刻动手把某种数据库整合到你的Python应用程序当中。

在Python世界里,无需怀疑,与数据库协同工作已经几乎是所有应用程序的核心部分了。在本章中,我们将不仅仅使用”万能”的Python标准库,尽管我们需要从标准库开始。

作为一个软件工程师,在你的职业生涯中,你可能永远不需要学习数据库知识:如何使用命令行工具、如何使用SQL、如何添加和更新数据等。但是如果Python是你的编程工具,那么为你的Python应用添加数据库支持会让它事半功倍。下面我们先来介绍一下Python的DB-API,然后给出使用这个标准的例子。

我们的例子会使用开源的数据库系统。不过我们不会去讨论是开源产品还是商业产品更好。要适应其他的数据库也相当容易,需要特别提到的是亚伦·沃特(Aaron Watter)的Gadfly数据库,一个完全由Python代码写成的数据库系统。

从Python中访问数据库需要接口程序,接口程序是一个Python模块,它提供数据库客户端库(通常是C语言写成的)的接口供你访问。需要提到一点,所有Python接口程序都一定程度上遵守PythonDB-API规范,这也是本章的第一个主要主题。

图21-1演绎了Python数据库应用程序的结构(包括使用和不使用ORM)。你可以看到DB-API是数据库客户端C库的接口。

21.1 介绍 - 图9

图 21-1 数据库和应用程序之间的多层通讯

第一个框中一般是C/C++程序,你的程序通过DB-API兼容接口程序访问数据库。

ORM通过程序处理数据库细节来简化数据库开发。