Python连接SQL Server 2008数据库实战:pyodbc配置与中文乱码解决
本文详解Python使用pyodbc库连接SQL Server 2008数据库的完整流程,涵盖连接字符串配置、游标操作及事务提交。重点解决中文数据显示为乱码问题,通过指定UTF-8字符集参数实现正确显示,并提供完整代码示例供参考。
本文详细演示了Python访问SQL Server 2008数据库的具体实现方式,内容包含关键配置与常见问题处理,供开发者参考。
近期因项目需求,需在Windows平台下使用Python开发并连接SQL Server 2008数据库,开发环境基于Wing IDE 4.0。
由于此前未接触过SQL Server,此次开发过程也是一次实践学习,文中记录了前期开发阶段遇到的若干问题及解决方案。
一、pyodbc与pymssql库的选择分析
在Python开发中,需先选定第三方数据库接口库。目前主流选择包括pymssql和pyodbc,网上相关资料也主要集中在这两者。起初尝试安装并使用pymssql,但始终无法通过Python应用程序远程连接SQL Server数据库。由于对Windows平台配置不熟悉,查阅资料后得知该库依赖特定驱动及变量设置,操作复杂且未果,最终放弃并改用pyodbc。尽管pyodbc也遇到少量小问题,但整体配置过程较为顺利。
二、pyodbc库接口功能说明
利用Python第三方库访问SQL Server数据库的过程相对简单。除SQL Server外,该库还支持其他遵循标准DB-API 2.0规范的数据库。核心操作流程仅需四步:建立并连接数据库(connect)、获取游标指针、执行SQL语句、关闭数据库连接。
1. 建立数据库连接
或者采用以下键值对形式:
此处对连接参数进行简要说明:
DRIVER='{SQL Server}'此参数通常固定不变,除非SQL Server配置发生更改。
SERVER:指定数据库服务器名称,而非IP地址(如192.168.0.X)。该名称在安装时设定,例如本例中的服务器名为:ZHANGHUAMIN\MSSQLSERVER_ZHM。
DATABASE:指定SQL Server中已存在的具体数据库名称。使用此connect接口前,目标数据库必须已在SQL Server中创建,否则连接将失败。
UID:登录用户名。
PWD:登录密码。
连接成功后,该函数将返回一个数据库连接句柄对象。
2. 获取游标指针
cursor = cnxn.cursor()
后续对数据库执行的所有SQL语句,均需通过该游标指针进行调用。
3. 执行数据库SQL操作
cursor.execute("select user_id, user_name from users") #调用游标指针的execute方法执行sql语句
row = cursor.fetchone() #sql语句执行结果的获取,如果需要一次获取多条记录,可以使用cursor.fetchall()方法
if row:
print row
执行完SQL语句后,若涉及数据变更需提交事务,可使用以下接口:
cnxn.commit()
特别注意:在创建数据库或数据表时,若未执行事务提交,在SQL Server 2008终端中将无法看到新建的数据库或表。提交事务后,即可通过终端查询语句即时查看结果。注:提交事务的commit方法归属于数据库连接句柄对象。
4. 关闭数据库连接
cnxn.close()
其操作逻辑与文件关闭类似,此处不再赘述。
三、Python操作SQL Server 2008完整示例
#!/usr/bin/python
#coding=utf-8
#-------------------------------------------------------------------------------
# Name: datamapper.py
# Purpose: using pyodbc library to operate database
#
# Author: huamin.zhang
#
# Created: 20/04/2013
#-------------------------------------------------------------------------------
import pyodbc
import time
class ODBC_MS:
''''' 对pyodbc库的操作进行简单封装
pyodbc库的下载地址:http://code.google.com/p/pyodbc/downloads/list
使用该库时,需要在Sql Server Configuration Manager里面将TCP/IP协议开启
此类完成对数据库DB的连接/查询/执行操作
正确的连接方式如下:
cnxn = pyodbc.connect('DRIVER={SQL SERVER};SERVER=ZHANGHUAMIN\MSSQLSERVER_ZHM;DATABASE=AdventureWorks2008;UID=sa;PWD=wa1234')
cnxn = pyodbc.connect(DRIVER='{SQL SERVER}',SERVER=r'ZHANGHUAMIN\MSSQLSERVER_ZHM',DATABASE='AdventureWorks2008',UID='sa',PWD='wa1234',charset="utf-8")
'''
def __init__(self, DRIVER,SERVER, DATABASE, UID, PWD):
''''' initialization '''
self.DRIVER = DRIVER
self.SERVER = SERVER
self.DATABASE = DATABASE
self.UID = UID
self.PWD = PWD
def __GetConnect(self):
''''' Connect to the DB '''
if not self.DATABASE:
raise(NameError,"no setting db info")
self.conn = pyodbc.connect(DRIVER=self.DRIVER, SERVER=self.SERVER, DATABASE=self.DATABASE, UID=self.UID, PWD=self.PWD, charset="UTF-8")
#self.conn = pyodbc.connect(DRIVER=self.DRIVER, SERVER=self.SERVER, DATABASE=self.DATABASE, UID=self.UID, PWD=self.PWD)
cur = self.conn.cursor()
if not cur:
raise(NameError,"connected failed!")
else:
return cur
def ExecQuery(self, sql):
''''' Perform one Sql statement '''
cur = self.__GetConnect() #建立链接并创建数据库操作指针
cur.execute(sql)#通过指针来执行sql指令
ret = cur.fetchall()#通过指针来获取sql指令响应数据
cur.close()#游标指标关闭
self.conn.close()#关闭数据库连接
return ret
def ExecNoQuery(self,sql):
''''' Person one Sql statement like write data, or create table, database and so on'''
cur = self.__GetConnect()
cur.execute(sql)
self.conn.commit()#连接句柄来提交
cur.close()
self.conn.close()
def main():
ms = ODBC_MS('{SQL SERVER}', r'ZHANGHUAMIN\MSSQLSERVER_ZHM', 'zhm_db', 'sa', 'wa1234')#zhm_db数据库是在sql server 终端里先创建好的
#ms.ExecNoQuery("drop table Customers_test")
sql = '''''CREATE TABLE Customers_test
(
CustomerNo int IDENTITY NOT NULL,
CustomerName varchar(30) NOT NULL,
Address1 nvarchar(30) NOT NULL ,
Address2 nvarchar(30) NOT NULL,
City nvarchar(20) NOT NULL,
State nchar(20) NOT NULL,
Zip varchar(10) NOT NULL,
Contact varchar(25) NOT NULL,
Phone char(15) NOT NULL,
FedIDNo varchar(9) NOT NULL,
DateInSystem smalldatetime NOT NULL
);'''
ms.ExecNoQuery(sql)
#注意:在进行插入操作时,自增长度不能够写入
sql = u'''''insert into Customers_test
(
CustomerName,
Address1,
Address2,
City,
State,
Zip,
Contact,
Phone,
FedIDNo,
DateInSystem
)
VALUES
(
'zhm', '北京市朝阳区', '北京市朝阳区', '北京', '哈哈','3625514', '18001226509', '010-88765879', '21', '2012-09-09'
);
'''
ms.ExecNoQuery(sql)
if __name__ == '__main__':
main()
说明:此前连接了SQL Server自带的AdventureWorks2008数据库示例,并在其中创建了数据表Customers_test,插入了一条记录。但在SQL Server 2008终端使用Select * FROM Customers_test查询时,包含中文信息的字段显示为“??????”乱码。经过排查,推测原因可能是AdventureWorks2008数据库存在某些未公开的约束或编码设置,导致不支持中文编码。而在自行创建的zhm_db数据库中,创建相同数据表并插入记录后,通过SQL Server终端查询中文显示正常。
为解决此问题,需在Python代码中增加:#coding = utf-8声明编码,并在连接字符串connect参数中增加charset = "utf-8"以指定字符集为utf-8,从而避免乱码出现。
最终在SQL Server 2008终端使用SELECT * FROM Customers_test查询,结果显示正常。

如需了解更多Python相关技术,可参考本站专题:《Python常见数据库操作技巧汇总》、《Python编码操作技巧总结》、《Python数据结构与算法教程》、《Python Socket编程技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》。
希望本文所述内容对大家的Python程序设计工作有所帮助。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









