использование pyodbc на человечности для вставки поля изображений на SQL Server

«Комментарии - это ложь»

Комментарии не выполняются и легко игнорируются. Намерение лучше выразить с помощью ясного, переработанного кода, проиллюстрированного модульными тестами. (Конечно, модульные тесты написаны TDD ...)

Мы не пишем комментарии, потому что они многословны и скрывают то, что на самом деле происходит в коде. Если вы чувствуете необходимость комментировать - выясните, что не ясно в коде, и реорганизуйте / напишите более четкие тесты, пока нет необходимости комментировать ...

... кое-что, чему я научился из экстремального программирования (конечно, предполагается, что вы установили командные нормы для очистки кода ...)

7
задан marc_s 2 December 2009 в 11:20
поделиться

2 ответа

Ха, сразу после предложения награды я нашел решение.

Вы должны использовать SET TEXTSIZE 2147483647 в запросе в дополнение к тексту параметр конфигурации размера в /etc/freetds/freetds.conf .

Я использовал

cur.execute('SET TEXTSIZE 2147483647 SELECT myimage FROM testing WHERE id = 1')

И все работало нормально.

Странно то, что в документации FreeTDS говорится о параметре конфигурации размера текста:

значение по умолчанию TEXTSIZE , в байтах. Для типов данных текст и изображение устанавливает максимальную ширину любого возвращаемого столбца. Ср. установите TEXTSIZE в документации T-SQL для вашего сервера.

В конфигурации также указано, что максимальное значение (и значение по умолчанию) составляет 4 294 967 295. Однако при попытке использовать это значение в запросе я получаю сообщение об ошибке, максимальное число, которое я мог бы использовать в запросе, - 2 147 483 647 (половина).

Исходя из этого объяснения, я подумал, что достаточно установить только этот параметр конфигурации. Оказалось, что я ошибался, установка TEXTSIZE в запросе устранила проблему.

Ниже приведен полный рабочий код:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import pyodbc
import urllib2

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()
cur = con.cursor()
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, (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('SET TEXTSIZE 2147483647 SELECT myimage FROM testing WHERE id = 1')
result = cur.fetchone()
returned_data = str(result[0])
print 'Original: %d; Returned; %d' % (len(data), len(returned_data))
assert data == returned_data
5
ответ дан 7 December 2019 в 03:19
поделиться

Я думаю, вам следует использовать экземпляр pyodbc.Binary , чтобы обернуть данные:

cur.execute('INSERT INTO testing (myimage) VALUES (?)', (pyodbc.Binary(data),))

Получение должно be

cur.execute('SELECT myimage FROM testing')
print "image bytes: %r" % str(cur.fetchall()[0][0])

ОБНОВЛЕНИЕ: Проблема в прошивке. Измените SQL-код вставки на следующее:

"""DECLARE @txtptr varbinary(16)

INSERT INTO testing (myimage) VALUES ('')
SELECT @txtptr = TEXTPTR(myimage) FROM testing 
WRITETEXT testing.myimage @txtptr ?
"""

Я также обновил ошибку, которую допустил при использовании атрибута value в коде поиска.

С этим изменением я могу вставлять и извлекать изображение 320K JPEG в база данных (полученные данные идентичны вставленным данным).

NB Тип данных image устарел и заменен на varbinary (max) в более поздних версиях SQL Server. Однако такая же логика для вставки / извлечения должна применяться для столбца нового типа.

3
ответ дан 7 December 2019 в 03:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: