Tôi đang sử dụng Ubuntu 9,04sử dụng pyodbc trên ubuntu để chèn một lĩnh vực hình ảnh trên SQL Server
Tôi đã cài đặt các phiên bản gói sau:
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
Tôi đã cấu hình /etc/unixodbc.ini
như thế này:
[FreeTDS]
Description = TDS driver (Sybase/MS SQL)
Driver = /usr/lib/odbc/libtdsodbc.so
Setup = /usr/lib/odbc/libtdsS.so
CPTimeout =
CPReuse =
UsageCount = 2
Tôi đã định cấu hình /etc/freetds/freetds.conf
như sau:
[global]
tds version = 8.0
client charset = UTF-8
text size = 4294967295
Tôi đã chộp lấy pyodbc sửa đổi 31e2fae4adbf1b2af1726e5668a3414cf46b454f
từ http://github.com/mkleehammer/pyodbc
và cài đặt nó sử dụng "python setup.py install
"
Tôi có một máy cửa sổ với Microsoft SQL Server 2000 cài đặt trên mạng nội bộ của tôi, và lắng nghe trên ip địa phương địa chỉ 10.32.42.69. Tôi có một cơ sở dữ liệu rỗng được tạo với tên "Chung". Tôi có người dùng "sa" với mật khẩu "bí mật" với đầy đủ đặc quyền.
Tôi đang sử dụng mã python sau để thiết lập kết nối:
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()
Tất cả mọi thứ TRÌNH đến thời điểm này. Tôi đã sử dụng Enterprise Manager của SQLServer trên máy chủ và bảng mới là ở đó. Bây giờ tôi muốn chèn một số dữ liệu trên bảng.
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 (?)"
Bây giờ ở đây về câu hỏi ban đầu của tôi, tôi đã gặp khó khăn trong sử dụng cur.execute(sql, (data,))
nhưng bây giờ tôi đã chỉnh sửa câu hỏi, bởi vì sau câu trả lời Vinay Sajip của bên dưới (THANKS), tôi đã thay đổi nó để:
cur.execute(sql, (pyodbc.Binary(data),))
con.commit()
Và chèn hoạt động hoàn hảo. Tôi có thể khẳng định kích thước của dữ liệu được chèn bằng cách sử dụng mã kiểm tra sau:
cur.execute('SELECT DATALENGTH(myimage) FROM testing WHERE id = 1')
data_inside = cur.fetchone()[0]
assert data_inside == len(data)
nào đi hoàn hảo !!!
Hiện tại, sự cố đang được khôi phục dữ liệu.
tôi đang cố gắng tiếp cận chung:
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
Tuy nhiên thất bại !!
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
Tôi đã đặt tất cả mã ở trên vào một tệp here, để dễ dàng kiểm tra bất kỳ ai muốn trợ giúp.
Bây giờ cho câu hỏi:
Tôi muốn mã python chèn tệp hình ảnh vào mssql. Tôi muốn truy vấn lại hình ảnh và hiển thị nó cho người dùng.
Tôi không quan tâm đến loại cột trong mssql.Tôi đang sử dụng loại cột "IMAGE
" trên ví dụ, nhưng bất kỳ loại nhị phân/blob nào sẽ làm, miễn là tôi nhận được dữ liệu nhị phân cho tệp mà tôi đã chèn trở lại không bị hỏng. Vinay Sajip nói dưới đây rằng đây là kiểu dữ liệu ưa thích cho điều này trong SQL SERVER 2000.
Dữ liệu hiện đang được chèn mà không có lỗi, tuy nhiên khi tôi lấy dữ liệu, chỉ 4k được trả về. (Dữ liệu được cắt ngắn trên 4096).
Tôi làm cách nào để làm việc đó?
CÁC CHỈNH SỬA: Câu trả lời Vinay Sajip của dưới đây đã cho tôi một gợi ý để sử dụng pyodbc.Binary trên sân. Tôi đã cập nhật câu hỏi cho phù hợp. Cảm ơn Vinay Sajip!
Nhận xét của Alex Martelli đã cho tôi ý tưởng sử dụng hàm MS SQL DATALENGTH
để kiểm tra xem dữ liệu có được tải đầy đủ trên cột hay không. Cảm ơn Alex Martelli!
gì thế nào bạn nhận được khi bạn 'SELECT DATALENGTH (myimage) FROM testing'? Ít nhất điều này sẽ cho bạn biết nếu vấn đề của bạn là với lưu trữ hoặc với lấy. –