13.1.1 全局变量
任何支持2.0版本DB API的数据库模块都必须定义3个描述模块特性的全局变量。这样做的原因时API设计的很灵活,以支持不同的基础机制、避免过多包装,可如果想让程序同时应用于几个数据库,那可是件麻烦事了,因为需要考虑到各种可能出现的状况。
变量名 用途
apilevel 所使用的python DB API版本
threadsafety 模块的线程安全等级
paramstyle 在SQL查询中使用的参数风格
API级别是个字符串常量,提供正在使用的API版本号。
线程安全性等级是个取值范围0~3的整数。0表示线程完全不共享模块,而3表示模块是安全线程安全的。1表示线程本身可以共享模块,但不对连接共享。如果不使用多个线程,那么完全不用担心这个变量。
参数风格表示执行多次类似查询的时候,参数是如何被拼接到SQL查询中的。
13.1.2 异常
为了能尽可能准确的处理错误,API中定义了一些异常类。它们被定义在一种层次结构中,所以可以通过一个except块捕捉多种异常。
13.1.3 连接和游标
为了使用基础数据库系统,首先必须连接到它。这个时候需要使用具有恰当名称的connect函数,该函数有很多参数,而具体使用哪个参数取决于数据库。
connect函数的常用参数
dsn 数据源名称,给出该参数表示数据库依赖
user 用户名
password 用户密码
host 主机名
database 数据库名
connect函数返回连接对象,这个对象表示目前和数据库的会话。
连接对象方法
close() 关闭连接之后,连接对象和它的游标均不可用
commit() 如果支持的话就提交挂起的事务,否则不做任何事
rollback() 回滚挂起的事务(可能不可用)
cursor() 返回连接的游标对象
cursor方法将我们引入另外一个主题:游标对象。通过游标执行sql查询并检查结果。游标比连接支持更多的方法。
13.1.4 类型
数据库对插入到具有某种类型的列中的值有不同的要求,是为了能正确地与基础sql数据库进行交互操作,DB API定义了用于特殊类型和值的构造函数及常量。
13.2.1 入门
这里以SQLite数据库作为示例。
将SQLite作为名为sqlite3的模块导入。之后就可以创建一个到数据库文件的连接----如果文件不存在就会被创建----通过提供一个文件名:
>>>import sqlite3
>>>conn = sqlite3.connect(‘somedatabase.db‘)
之后就能获得连接的游标:
>>>curs = conn.cursor()
这个游标可以用来执行sql查询,完成查询并且做出某些更改后确保已经进行了提交,这样才可以将这些修改真正的保存到文件中:
>>>conn.commit()
可以在每次修改数据库后都进行提交,而不是仅仅在准备关闭时才提交,准备关闭数据库时,使用close方法:
>>>conn.close()
13.2.2 数据库应用程序示例
1.创建和填充表
为了真正地创建数据库表并且向其中插入数据,写个完全独立的一次程序可能是最简单的方案。
下面程序创建了叫做food的表和适当的字段,并且从ABBREV.txt中读取数据。之后分解析,然后通过调用curs.execute执行SQL的INSERT语句将文本字段中的值插入到数据库中。
将数据导入数据库
import sqlite3
def convert(value)
if value.startswith(‘~‘):
return value.strip(‘~‘)
if not value:
value = ‘0‘
return float(value)
conn = sqlite3.connect(‘food.db‘)
curs = conn.cursor()
curs.execute(‘‘‘
CREATE TABLE food (
id TEXT PRIMARY KEY,
desc TEXT,
water FLOAT,
kcal FLOAT,
ash FLOAT,
fiber FLOAT
)
‘‘‘)
query = ‘INSERT INTO food VALUES(?,?,?,?,?,?)‘
for line in open(‘ABBREV.txt‘):
fileds = line.split(‘^‘)
vals = [convert(f) for f in fileds[:filed_count]]
curs.execute(query,vals)
conn.commit()
conn.close()
当运行这个程序时,它会创建一个叫做food.db的新文件,它包含数据库中的所有数据。
2.搜索和处理结果
使用数据库很简单。再说一次,需要创建连接并且获得该链接的游标。使用execute方法执行sql查询,用fetchall等方法提取结果。
展示一个将SQL SELECT条件查询作为命令行参数,之后按记录格式打印出返回行的小程序。可以用下面的命令尝试这个程序:
$python food_query.py "kcal <= 100 AND fiber >= 10 ORDER BY sugar"
运行的时候可能注意到有个问题。第一行,生橘子皮看起来不含任何糖分,这是因为在数据文件中这个字段丢失了。可以改进刚才的导入脚本检测条件,然后插入None带代替真实的值来表示丢失的数据。可以使用如下条件:
"kcal <= 100 AND fiber >= 10 AND sugar ORDER BY sugar"
请求在任何返回行中包含实际数据的糖分字段。
食品数据库查询程序(food_query.py)
import sqlite3,sys
conn = sqlite3.connect(‘food.db‘)
curs = conn.cursor()
query = ‘SELECT * FROM food WHERE %s‘ % sys.argv[1]
print query
curs.execute(query)
names = [f[0] for f in curs.description]
for row in curs.fetchall():
for pair in zip(names,row):
print ‘%s: %s‘ % pair