Python数据库连接指南:DB-API规范与实战详解
本文深入解析Python DB-API规范,详细讲解使用connect创建连接、通过cursor执行SQL及处理结果的标准流程。涵盖MySQLdb与psycopg2的参数差异、游标常用方法(fetchone/fetchall/execute)及错误处理机制,并提供完整的数据库操作代码示例,帮助开发者实现跨数据库的稳定连接与高效开发。
前言
在Python开发中,无论是连接MySQL、SQL Server、PostgreSQL还是SQLite,通常都需要借助游标(Cursor)来执行数据库操作。因此,掌握Python DB-API规范是进行数据库编程的基础。
Python中的各类数据库接口模块均遵循Python DB-API规范。该规范定义了一系列核心对象及存取方式,旨在为底层数据库系统提供统一的访问接口。由于DB-API屏蔽了不同数据库的差异,使得代码在不同数据库平台间的移植变得简便。
Python连接数据库的标准流程如下:

第一步:使用connect创建连接对象
通过调用connect方法生成一个connection对象,后续所有数据库操作均通过该对象进行。符合标准的数据库模块均实现了此方法。
connect函数的常用参数包括:
- user:用户名
- password:密码
- host:主机名
- database:数据库名称
- dsn:数据源名称
数据库连接参数也可通过DSN字符串形式提供,例如:connect(dsn='host:MYDB',user='root',password=' ')。需注意,不同数据库接口的实现可能存在差异,并非完全严格遵循规范。例如,MySQLdb模块使用db参数而非规范推荐的database参数来指定目标数据库:
MySQLdb连接时的可用参数说明:
- host:数据库主机名,默认为本地主机
- user:数据库登录用户名,默认为当前系统用户
- passwd:数据库登录密码,默认为空
- db:要访问的数据库名称,无默认值
- port:MySQL服务使用的TCP端口,默认为3306
- charset:数据库编码格式
psycopg2连接时的可用参数说明:
- dbname:数据库名称(适用于DSN连接模式)
- database:数据库名称
- user:用户名
- password:密码
- host:服务器地址,若未提供则默认连接Unix Socket
- port:连接端口,默认为5432
生成的connect对象包含以下常用方法:
- close():关闭连接对象,关闭后无法继续操作,需重新创建连接
- commit():提交当前事务。对于支持事务的数据库,若执行增删改操作后未调用commit,数据库默认将回滚更改
- rollback():取消当前事务,回滚至事务开始前的状态
- cursor():创建并返回一个游标对象,用于执行SQL语句
第二步:使用cursor创建游标对象
游标(Cursor)对象包含以下属性和方法:
常用方法包括:
- close():关闭游标对象
- fetchone():获取结果集中的下一行数据
- fetchmany([size = cursor.arraysize]):获取结果集中的下几行数据,数量由size指定
- fetchall():获取结果集中剩余的所有行数据
- execute(sql[, args]):执行单条数据库查询或命令
- executemany(sql, args):批量执行多条数据库查询或命令
常用属性包括:
- connection:创建该游标所关联的数据库连接对象
- arraysize:使用fetchmany()时一次获取的记录数,默认为1
- lastrowid:获取最后插入行的ID,功能类似于PHP中的last_inset_id()
其他方法包括:
- __iter__():创建可迭代对象(可选实现)
- next():获取结果集的下一行(若支持迭代协议)
- nextset():移动到下一个结果集(若支持多结果集)
- callproc(func[,args]):调用数据库存储过程
- setinputsizes(sizes):设置输入参数的最大值(必须存在,具体实现可选)
- setoutputsizes(sizes[,col]):设置大字段fetch的最大缓冲区大小
其他属性包括:
- description:返回游标的活动状态元组(包含7个元素):(name, type_code, display_size, internal_size, precision, scale, null_ok)。其中name和type_code是必需字段
- rowcount:最近一次execute()操作创建或影响的行数
- messages:游标执行后数据库返回的信息元组(可选)
- rownumber:当前结果集中游标所在行的索引,起始行号为0
DB-API中定义的错误类型:
错误类的继承层次结构如下:
StandardError |__Warning |__Error |__InterfaceError |__DatabaseError |__DataError |__OperationalError |__IntegrityError |__InternalError |__ProgrammingError |__NotSupportedError
数据库操作实战示例
具体代码如下:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# *************************************************************
# Filename @ operatemysql.py
# Author @ Huoty
# Create date @ 2015-08-16 10:44:34
# Description @
# *************************************************************
import MySQLdb
# Script starts from here
# 连接数据库
db_conn = MySQLdb.connect(host = 'localhost', user= 'root', passwd = '123456')
# 如果已经创建了数据库,可以直接用如下方式连接数据库
#db_conn = MySQLdb.connect(host = "localhost", user = "root",passwd = "123456", db = "testdb")
"""
connect方法常用参数:
host: 数据库主机名.默认是用本地主机
user: 数据库登陆名.默认是当前用户
passwd: 数据库登陆的秘密.默认为空
db: 要使用的数据库名.没有默认值
port: MySQL服务使用的TCP端口.默认是3306
charset: 数据库编码
"""
# 获取操作游标
cursor = db_conn.cursor()
# 使用 execute 方法执行SQL语句
cursor.execute("SELECT VERSION()")
# 使用 fetchone 方法获取一条数据库。
dbversion = cursor.fetchone()
print "Database version : %s " % dbversion
# 创建数据库
cursor.execute("create database if not exists dbtest")
# 选择要操作的数据库
db_conn.select_db('dbtest');
# 创建数据表SQL语句
sql = """CREATE TABLE if not exists employee(
first_name CHAR(20) NOT NULL,
last_name CHAR(20),
age INT,
sex CHAR(1),
income FLOAT )"""
try:
cursor.execute(sql)
except Exception, e:
# Exception 是所有异常的基类,这里表示捕获所有的异常
print "Error to create table:", e
# 插入数据
sql = """INSERT INTO employee(first_name,
last_name, age, sex, income)
VALUES ('%s', '%s', %d, '%s', %d)"""
# Sex: Male男, Female女
employees = (
{"first_name": "Mac", "last_name": "Mohan", "age": 20, "sex": "M", "income": 2000},
{"first_name": "Wei", "last_name": "Zhu", "age": 24, "sex": "M", "income": 7500},
{"first_name": "Huoty", "last_name": "Kong", "age": 24, "sex": "M", "income": 8000},
{"first_name": "Esenich", "last_name": "Lu", "age": 22, "sex": "F", "income": 3500},
{"first_name": "Xmin", "last_name": "Yun", "age": 31, "sex": "F", "income": 9500},
{"first_name": "Yxia", "last_name": "Fun", "age": 23, "sex": "M", "income": 3500}
)
try:
# 清空表中数据
cursor.execute("delete from employee")
# 执行 sql 插入语句
for employee in employees:
cursor.execute(sql % (employee["first_name"], \
employee["last_name"], \
employee["age"], \
employee["sex"], \
employee["income"]))
# 提交到数据库执行
db_conn.commit()
# 对于支持事务的数据库, 在Python数据库编程中,
# 当游标建立之时,就自动开始了一个隐形的数据库事务。
# 用 commit 方法能够提交事物
except Exception, e:
# Rollback in case there is any error
print "Error to insert data:", e
#b_conn.rollback()
print "Insert rowcount:", cursor.rowcount
# rowcount 是一个只读属性,并返回执行execute(方法后影响的行数。)
# 数据库查询操作:
# fetchone() 得到结果集的下一行
# fetchmany([size=cursor.arraysize]) 得到结果集的下几行
# fetchall() 返回结果集中剩下的所有行
try:
# 执行 SQL
cursor.execute("select * from employee")
# 获取一行记录
rs = cursor.fetchone()
print rs
# 获取余下记录中的 2 行记录
rs = cursor.fetchmany(2)
print rs
# 获取剩下的所有记录
ars = cursor.fetchall()
for rs in ars:
print rs
# 可以用 fetchall 获得所有记录,然后再遍历
except Exception, e:
print "Error to select:", e
# 数据库更新操作
sql = "UPDATE employee SET age = age + 1 WHERE sex = '%c'" % ('M')
try:
# 执行SQL语句
cursor.execute(sql)
# 提交到数据库执行
db_conn.commit()
cursor.execute("select * from employee")
ars = cursor.fetchall()
print "After update: ------"
for rs in ars:
print rs
except Exception, e:
# 发生错误时回滚
print "Error to update:", e
db.rollback()
# 关闭数据库连接
db_conn.close()
其他参考文档:
https://www.python.org/dev/peps/pep-0249/
http://wiki.python.org/moin/DatabaseInterfaces
总结
本文介绍了Python连接数据库的核心机制与DB-API规范,希望能为读者的学习或工作提供有益参考。如有任何疑问,欢迎留言交流。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













