14.4 创建数据库和表
相比Python的列表和字典,数据库需要更多的已定义结构。
在我们创建数据库表之前,我们必须预先告诉数据库表和列的命名,以及计划保存到列中和数据类型。当数据库软件预先知道每列中的数据类型,它就可以选择最有效的方式保存和查找数据。
你可以通过以下链接,查看SQLite支持的各种数据类型:
http://www.sqlite.org/datatypes.html
预先定义数据结构看起来不是很方便,但它可以使你快速访问数据即使数据库中包含了大量数据。
以下代码创建了一个数据库文件,以及一个名为Tracks、内有两个列的表:
import sqlite3 conn = sqlite3.connect('music.sqlite3') cur = conn.cursor() cur.execute('DROP TABLE IF EXISTS Tracks') cur.execute('CREATE TABLE Tracks (title TEXT, plays INTERGER)') conn.close()
连接操作创建了一个至当前目录下名为music.sqlite3数据库文件的“连接”。如果这个文件不存在,它会创建一个。因为有些时候数据库文件保存在一个与应用程序独立的数据库服务器上,所以打开数据库文件的操作被称为“连接”。在我们这个简单的例子里,数据库文件和代码则保存在同一目录下。
光标类似文件句柄,我们利用光标来完成数据操作,调用cursor()和调用open()处理文本文件在概念上非常相似。
一旦我们获取光标,我们就可以使用execute()方法来执行数据库命令。数据库命令通过一种特殊的、已被标准化的语言来表示,使得我们只学一种语言就可操做不同厂家的数据库。这种特殊语言称为结构化查询语言,简称SQL。详细信息可查阅:http://en.wikipedia.org/wiki/SQL。
在我们的示例中,在我们的数据中执行了两条SQL命令。作为约定,我们将SQL关键字用大写表示,而我们添加的表名和列名将用小写表示。
第一条SQL命令从数据库中删除名为Tracks的表(如果存在),这种方式可以简单地让我们一遍又一遍的运行相同的程序来创建表Tacks,而不会引起错误。注意DROP TABLE命令将从数据库中删除表以及表中的所有内容。
cur.execute('DROP TABLE IF EXISTS Tracks ')
第二条命令创建了一张名为Tracks的表,表中包含两个列,分别名为文本类型的title和整数类型的plays。
cur.execute('CREATE TABLE Tracks (title TEXT, plays INTEGER)')
现在我们创建了表Tracks,我们可以用SQL INSERT命令往表中插入数据。所以我们再次连接数据库获取光标,并执行SQL命令。
SQL INSERT命令指明我们要往哪张表插入数据,然后通过列出我们想包含的字段(title, plays) 来定义一个新行,后面跟着的VALUE来定义要放入新行中的数据。我们用问号(?,?)来表示我们要传入的是一个元组,其实际数值是execute()调用中的第二个参数('My Way', 15)。
import sqlite3 conn = sqlite3.connect('music.sqlite3') cur = conn.cursor() cur.execute('INSERT INTO Tracks (title, plays) VALUES (?, ?)', ('Thunderstruck', 20)) cur.execute('INSERT INTO Tracks (title, plays) VALUES (?, ?)', ('My Way', 15)) conn.commit() print('Tracks:') cur.execute('SELECT title, plays FROM Tracks') for row in cur: print (row) cur.execute('DELETE FROM Tracks WHERE plays < 100') conn.commit() conn.close()
首先我们往表里插入了两行数据,然后使用commit()方法促使数据被写入数据库文件,表Tracks的内容如下图所示:
然后我们使用SELECT命令获取我们刚刚插入的行。在SELECT命令中,我们指明想从哪张表读取数据,以及想读取的列。在我们执行SELECT语句后,光标成为一个可以用for语句遍历的对象。为了提高效率,在执行SELECT命令时,光标并不读取数据库中的所有信息,而只按需读取在for语句中遍历的信息。这个程序的输出如下:
Tracks:
('Thunderstruck', 20)
('My Way', 15)
我们的循环找到了两行数据,每一行是Python的元组类型,元组的第一个值是歌名title,第二个值是播放的次数plays。
为了让我们的程序多次运行,在程序的最后,我们执行一个SQL DELETE命令删除了我们创建的行。DELETE命令中的WHERE子句可以让我们限制一个条件,这样我们可以要求数据库只将命令应用到符合条件的行。在这个例子里,限制条件恰好应用到所有行,清空了整个表,使得我们可以重复运行程序。在DELETE命令之后,我们再次调用commit()方法促使数据库删除数据。
注:文章原文为Dr. Charles Severance 的 《Python for Informatics》。文中代码用3.4版改写,并在本机测试通过。