求教一些链接ms sql的问题

12 views
Skip to first unread message

Wuvist

unread,
Jul 20, 2006, 9:05:58 AM7/20/06
to python.cn
大家好~偶是个python新手,第一次在此讨论区发贴就是来问问题,还望大家多多照顾......

偶一向是使用.net的,最近想用python做一些东西,但是用python新做的这些东西,还是需要使用到原来ms
sql server
2005里面的数据......自己折腾很久,似乎还是找不到一个妥善的方案......

我已经试过adodbapi
http://test.sf.net/projects/adodbapi/),感觉似乎bug多多......执行:
cs.execute('select 1 as t1 where 1=?', [1])
都会出莫名的错误。

本来看到从php
port过来的adodb还以为找到救星,无奈它底层居然是用mxODBC这个商业组件......一千多块美金实在太贵......

现在暂时只能使用python win自带的odbc
interface......虽然只支持DB-API spec
v1.0,但似乎勉强还可以用......

现在有几个问题:
1. 是否有比odbc interface更加高级点的免费库可以用呢?

2. 如果使用odbc
interface这个古老的东西的话,我是否可以认为因为它很简单,所以,效率应该很高?

3. 使用odbc
interface需要如何在执行存储过程的时候,获得output参数的值?

4. 因为DB-API
fetchone/all等的时候,返回的tuple是不包涵列名的,偶写了下面的小程序,大家能否帮忙提一下意见?小弟不胜感激~
import odbc

connstr="DSN=naruto;UID=sa;PWD=password"
c = odbc.odbc(connstr)

class DataRow:
ids = {}

def __init__(self, dt, description):
self.dt=dt
i = 0
if type(description) == list:
for it in description:
self.ids[it[0]] = i
i += 1
elif type(description) == dict:
self.ids = description

def __getitem__ (self, itemName):
if type(itemName) == int:
return self.dt[itemName]
else:
return self.dt[self.ids[itemName]]


class DataTable:
ids = {}

def __init__(self, dt, description):
self.dt=dt

i = 0
if type(description) == list:
for it in description:
self.ids[it[0]] = i
i += 1
elif type(description) == dict:
self.ids = description

def __getitem__ (self, itemName):
return DataRow(self.dt[itemName],self.ids)


def exeScalar(sql, parameters=None, sp=0):
if sp == 1:
sql = "exec " + sql

cs = c.cursor()
if parameters!=None:
cs.execute(sql,parameters)
else:
cs.execute(sql)

row = cs.fetchone()
cs.close()
if row == None:
return row
else:
return row[0]


def exeRow(sql, parameters=None, sp=0):
if sp == 1:
sql = "exec " + sql

cs = c.cursor()
if parameters!=None:
cs.execute(sql,parameters)
else:
cs.execute(sql)

row = cs.fetchone()
cs.close()
return DataRow(row,cs.description)
if row == None:
return None

dt = {}
i = 0
for it in cs.description:
dt[it[0]] = row[i]
dt[i] = row[i]
i += 1

return dt

def exeTable(sql, parameters=None, sp=0):
if sp == 1:
sql = "exec " + sql

cs = c.cursor()
if parameters!=None:
cs.execute(sql,parameters)
else:
cs.execute(sql)

dt = cs.fetchall()
cs.close()
return DataTable(dt,cs.description)

def exeNonQuery(sql, parameters=None, sp=0):
if sp == 1:
sql = "exec " + sql

cs = c.cursor()

if parameters!=None:
cs.execute(sql,parameters)
else:
cs.execute(sql)
cs.close()

刘鑫

unread,
Jul 20, 2006, 9:10:56 AM7/20/06
to pyth...@googlegroups.com
用Pywin32包的COM接口调用ADO就可以了,Pywin32是开源的。

2006/7/20, Wuvist <wuv...@gmail.com>:



--
欢迎访问:
http://blog.csdn.net/ccat

刘鑫
March.Liu

jejwe

unread,
Jul 20, 2006, 9:27:32 AM7/20/06
to pyth...@googlegroups.com
pymssql-0.7.4.win32-py2.4.exe

Wuvist

unread,
Jul 20, 2006, 9:27:53 AM7/20/06
to python.cn
呃……但是……我最初使用的adodbapi就是“用Pywin32包的COM接口调用ADO”的……
人家能开源出来应该也不是菜鸟,结果貌似还是bug多多……偶自己直接去重新发明一下轮子,恐怕更惨……

Wuvist

unread,
Jul 20, 2006, 9:32:15 AM7/20/06
to python.cn
感谢jejwe~5555555……偶之前怎么就没有搜到呢?

张骏

unread,
Jul 20, 2006, 9:40:35 AM7/20/06
to pyth...@googlegroups.com
Adodbapi 不应该在这么简单的应用上出现错误。

如果实在找不到解决方法,建议使用sqlalchemy。他已经比较完善的解决了数据库连接和跨线程的问题。

另外,可以使用pymssql
http://sourceforge.net/projects/pymssql
不过这个类库是绝对的client端游标(ms说法),如果你查一个表的所有数据,而这个数据又太大,会比较痛苦。

--
张骏 <zha...@foreseen-info.com>

敏捷来自Python
简单源于我们
丰元信信息技术有限公司

Python技术交流群:22507237

刘鑫

unread,
Jul 20, 2006, 10:11:19 AM7/20/06
to pyth...@googlegroups.com
ADODBAPI的设计目的是为ADO数据源提供兼容DBAPI协议的统计访问接口,所以有些ADO COM提供的功能它反而没有。直接调用ADO不算重新造轮子。我以前一直这样写数据库管理脚本。

2006/7/20, Wuvist <wuv...@gmail.com>:
呃……但是……我最初使用的adodbapi就是"用Pywin32包的COM接口调用ADO"的……
人家能开源出来应该也不是菜鸟,结果貌似还是bug多多……偶自己直接去重新发明一下轮子,恐怕更惨……


Wuvist

unread,
Jul 21, 2006, 1:30:13 AM7/21/06
to python.cn
呃……跟大家报告一下……

偶……最终还是用回了adodbapi……
之前偶说的错误是因为偶参数传递的方式不对……
不应该是:


cs.execute('select 1 as t1 where 1=?', [1])

而应该是
cs.execute('select 1 as t1 where 1=%d' :(1))

貌似adodbapi跟pymssql都只能使用"sql cmd" :
(parameters)的方式去传递参数。

但是,这样子相当于是在拼SQL语句……很容易被注入……异常不爽……

另外,据pymssql的官方网站(http://pymssql.sourceforge.net/)说,pymssql应该是python里面链接数据库最快的方式:
“It's the most efficient method of accessing MS SQL Server's data
from Python scripts. If you care about performance, you can give it a
try.”

pymssql似乎无法获得数据列名,反复试了几次cursor.description的值都是None……这也是偶无奈改回adodbapi的原因……不知道是否是因为偶使用方式不对,还望各位大虾指点……

pymssql还有另一个严重问题便是无法查询类型为nText的数据……按照官方网站说法:
“There's no fix for this error. A workaround is to change the column
type to NVARCHAR (it doesn't exhibit this behaviour), or plain TEXT.”

很郁闷……

另外,pymssql还是可以在*nix、OSX里面使用的,不过,我之前的说法也是没错,它需要FreeTDS做支持……

FreeTDS跟ms sql 2005似乎合不来,需要把ms sql
2005数据库的兼容模式设为7.0!才可以正常使用,貌似这相当于把ms
sql 2005当作ms sql 6.5去使用了……ms sql 2000倒是没事……

至于sqlalchemy,它的底层用的便是adodbapi或者pymssql,加多一个层而已……

Wuvist

unread,
Jul 21, 2006, 1:45:17 AM7/21/06
to python.cn
汗~pymssql可以正常获得列名/description的……
但是,cursor的description会随着cs.close()而变成None。

nEO (a.k.a. gentoo.cn)

unread,
Jul 21, 2006, 1:48:49 AM7/21/06
to pyth...@googlegroups.com
On 7/21/06, Wuvist <wuv...@gmail.com> wrote:
(...)

另外,据pymssql的官方网站(http://pymssql.sourceforge.net/)说,pymssql应该是python里面链接数据库最快的方式:
"It's the most efficient method of accessing MS SQL Server's data
from Python scripts. If you care about performance, you can give it a
try."
我用pymssql的速度很快,应该没什么大问题.
 

pymssql似乎无法获得数据列名,反复试了几次cursor.description的值都是None……这也是偶无奈改回adodbapi的原因……不知道是否是因为偶使用方式不对,还望各位大虾指点……

应该是可以获得的,我用SQLObject包装数据库,可以得到列的名字
SQLObject使用的就是pymssql所以应该可以的.

pymssql还有另一个严重问题便是无法查询类型为nText的数据……按照官方网站说法:
"There's no fix for this error. A workaround is to change the column
type to NVARCHAR (it doesn't exhibit this behaviour), or plain TEXT."

很郁闷……

这个是比较讨厌的地方,  :(

另外,pymssql还是可以在*nix、OSX里面使用的,不过,我之前的说法也是没错,它需要FreeTDS做支持……

FreeTDS跟ms sql 2005似乎合不来,需要把ms sql
2005数据库的兼容模式设为7.0!才可以正常使用,貌似这相当于把ms
sql 2005当作ms sql 6.5去使用了……ms sql 2000倒是没事……
我用SQL Server 2000 Freetds ver 设置为8.0
从pymssql的文档来看,在windows下是可以支持2005的,因为windows下不用freetds

--
I'm the one, powered by nEO

张骏

unread,
Jul 21, 2006, 2:02:01 AM7/21/06
to pyth...@googlegroups.com
在 2006-7-21 13:30:13,"Wuvist" <wuv...@gmail.com> 写道:
> 呃……跟大家报告一下……
>
> 偶……最终还是用回了adodbapi……
> 之前偶说的错误是因为偶参数传递的方式不对……
> 不应该是:
> cs.execute('select 1 as t1 where 1=?', [1])
> 而应该是
> cs.execute('select 1 as t1 where 1=%d' :(1))
>
应该是支持参数方式执行sql的。

你试试:

cs.execute('select 1 as t1 where 1=?', 1 )

cs.execute('select 1 as t1 where 1=?', ( 1 ) )

Wuvist

unread,
Jul 21, 2006, 2:09:17 AM7/21/06
to python.cn
张骏 wrote:
> 你试试:
> cs.execute('select 1 as t1 where 1=?', 1 )
> 或
> cs.execute('select 1 as t1 where 1=?', ( 1 ) )

这两个我都试过,不行就是不行,莫非是偶rpwt?

Wuvist

unread,
Jul 21, 2006, 2:16:27 AM7/21/06
to python.cn
nEO (a.k.a. gentoo.cn) wrote:
> 我用SQL Server 2000 Freetds ver 设置为8.0
> 从pymssql的文档来看,在windows下是可以支持2005的,因为windows下不用freetds

嗯,windows下是可以,但是*nix下freetds无法链接sql server
2005,既便FreeTDS与sql server
2005的兼容等级都是8.0,必需都改成7.0的才可以......
传说ms sql 2005的8.0跟2000的8.0其实是不一样的......

Wuvist

unread,
Jul 21, 2006, 2:52:04 AM7/21/06
to python.cn
呼呼……
此刻又把adodbapi抛弃了……
改用pyodbc http://pyodbc.sourceforge.net/
很爽~
参数随便传递,没有注入危险
没有nText的问题
而且,支持直接以列名方式直接获取数据:
cursor.execute("select count(*) as photo_count from photos where
user_id=1")
row = cursor.fetchone()
print row.photo_count
Reply all
Reply to author
Forward
0 new messages