【发布时间】:2010-11-06 19:09:46
【问题描述】:
我正在使用 Ubuntu 9.04
我安装了以下软件包版本:
unixodbc and unixodbc-dev: 2.2.11-16build3
tdsodbc: 0.82-4
libsybdb5: 0.82-4
freetds-common and freetds-dev: 0.82-4
python2.6-dev
我已经这样配置/etc/unixodbc.ini:
[FreeTDS]
Description = TDS driver (Sybase/MS SQL)
Driver = /usr/lib/odbc/libtdsodbc.so
Setup = /usr/lib/odbc/libtdsS.so
CPTimeout =
CPReuse =
UsageCount = 2
我已经像这样配置/etc/freetds/freetds.conf:
[global]
tds version = 8.0
client charset = UTF-8
text size = 4294967295
我已经从http://github.com/mkleehammer/pyodbc 抓取了pyodbc 修订版31e2fae4adbf1b2af1726e5668a3414cf46b454f 并使用“python setup.py install”安装它
我的本地网络上安装了 Microsoft SQL Server 2000 的 Windows 机器,启动并监听本地 IP 地址 10.32.42.69。我有一个名为“Common”的空数据库。我有用户“sa”,密码为“secret”,拥有完全权限。
我正在使用以下 python 代码来设置连接:
import pyodbc
odbcstring = "SERVER=10.32.42.69;UID=sa;PWD=secret;DATABASE=Common;DRIVER=FreeTDS"
con = pyodbc.connect(odbcstring)
cur = con.cursor()
cur.execute("""
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'testing')
DROP TABLE testing
""")
cur.execute('''
CREATE TABLE testing (
id INTEGER NOT NULL IDENTITY(1,1),
myimage IMAGE NULL,
PRIMARY KEY (id)
)
''')
con.commit()
到目前为止,一切都有效。我在服务器上使用了 SQLServer 的企业管理器,新表就在那里。 现在我想在表格中插入一些数据。
cur = con.cursor()
# using web data for exact reproduction of the error by all.
# I'm actually reading a local file in my real code.
url = 'http://www.forestwander.com/wp-content/original/2009_02/west-virginia-mountains.jpg'
data = urllib2.urlopen(url).read()
sql = "INSERT INTO testing (myimage) VALUES (?)"
现在在我原来的问题上,我在使用 cur.execute(sql, (data,)) 时遇到了问题,但现在我已经编辑了这个问题,因为按照下面 Vinay Sajip 的回答(谢谢),我已将其更改为:
cur.execute(sql, (pyodbc.Binary(data),))
con.commit()
插入运行良好。我可以使用以下测试代码确认插入数据的大小:
cur.execute('SELECT DATALENGTH(myimage) FROM testing WHERE id = 1')
data_inside = cur.fetchone()[0]
assert data_inside == len(data)
通过完美!!!
现在问题在于检索数据。
我正在尝试通用方法:
cur.execute('SELECT myimage FROM testing WHERE id = 1')
result = cur.fetchone()
returned_data = str(result[0]) # transforming buffer object
print 'Original: %d; Returned: %d' % (len(data), len(returned_data))
assert data == returned_data
但是失败了!!
Original: 4744611; Returned: 4096
Traceback (most recent call last):
File "/home/nosklo/devel/teste_mssql_pyodbc_unicode.py", line 53, in <module>
assert data == returned_data
AssertionError
我已将以上所有代码放在一个文件here 中,以便于测试任何想要提供帮助的人。
现在问题来了:
我希望 python 代码将图像文件插入 mssql。我想查询图像并将其显示给用户。
我不关心 mssql 中的列类型。我在示例中使用“IMAGE”列类型,但任何二进制/blob 类型都可以,只要我得到未损坏的插入文件的二进制数据。 Vinay Sajip 在下面说,这是 SQL SERVER 2000 中的首选数据类型。
现在插入数据没有错误,但是当我检索数据时,只返回 4k。 (数据在 4096 被截断)。
我怎样才能做到这一点?
编辑:下面 Vinay Sajip 的回答给了我在现场使用 pyodbc.Binary 的提示。我已经相应地更新了这个问题。谢谢 Vinay Sajip!
Alex Martelli 的评论让我想到了使用DATALENGTH MS SQL 函数来测试数据是否已完全加载到列上。谢谢亚历克斯·马泰利!
【问题讨论】:
-
当您“从测试中选择 DATALENGTH(myimage)”时会得到什么?至少这会告诉你问题是存储还是检索。
标签: python sql-server image pyodbc freetds