之前并未使用过Sql Server数据库,这次也当作一次练手,并把这次数据库前期开发过程中遇到的一些问题进行记录。
在使用python语言进行开发之前,需要确定使用哪种第三方的数据库操作接口,目前Python提供了一些库,如pymssql和pyodbc,目前网上资料比较多的也是这两个了。刚开始我尝试安装并使用了pymssql库,但是始终无法通过python应用程序远程访问连接Sql Server数据库,由于对windows平台又不太熟悉,网上查了一些资料未果,说是需要依赖feeds,还需要设置各种变量等,最终我放弃了它改用pyodbc,虽然也遇到一些小问题,但是总体来说非常顺利。
基于第三方python库来访问Sql Server数据库的过程非常简单(其实除了能访问sql server外,它还可以访问其它数据库,因为它们都基于标准的DB-API2.0标准),总共只需要四步:打开并连接数据库connect、 获取游标指针、执行数据库sql操作、关闭数据库连接
1 打开连接数据库
cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=testdb;UID=me;PWD=pass')
或者是:cnxn = pyodbc.connect(DRIVER=‘{SQL Server}’,SERVER=‘localhost’,DATABASE=‘testdb’,UID=‘me’,PWD=‘pass')这里简单说明一下参数:
DRIVER=‘{SQL Server}'这个一般是固定的,除非你在Sql Server作了更改。
SERVER:此参数为数据库服务器名称,不是"192.168.0.X"这种,一般在安装时命名好了,我的是:ZHANGHUAMIN\MSSQLSERVER_ZHM
DATABASE:此参数指的是Sql Server内具体的数据库了,使用这个connect接口连接之前在sqlserver内应该是已经先创建好并存在的,否则连接不上。
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 Server2008终端上将找不到创建的数据库及数据表,如果提交后,在sql server2008通过终端的查询sql 语句就可以即时查到。注:提交事务的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 Server2008的终端上用Select * FROM Customers_test查询,结果对包含中文信息字段的数据变成如“??????”的乱码,经过倒腾了一上午,唯一可能解释的原因可能在于AdventureWorks2008数据库做了一些我不知道的约束,中文所对应的编码它不支持。 因为在如上例程中,我自己创建的zhm_db数据库,并在其中创建数据表,然后插入记录,同样的在Sql Server终端里用select查询,中文也是可以正常显示的。
注意,在python程序中需要增加:#coding = utf-8编码,并在连接connect内增加charset = "utf-8"指明字符集为utf-8编码即可。这样可以防止乱码的出现
最后在Sql Server 2008内通过终端使用SELECT * FROM Customers_test显示的结果如下: