Как извлечь байты из базы данных SQL Server и конвертировать в изображение в Python - PullRequest
0 голосов
/ 08 июля 2019

- я загружаю тестовые данные в свою базу данных SQL Server, используя python, и смог успешно взять изображения и разбить их на байты и сохранить их в базе данных, но при попытке извлечь байты и декодировать их в сохранить его как новый тип файла, все, что я получаю, это пустой файл изображения. Не уверен, что я здесь делаю неправильно ...

- Я пробовал несколько итераций, используя base64 из других уроков и подобных вопросов, но, похоже, не могу найти ту, которая решит мою проблему.

SQLCommand = ("SELECT Photo FROM Validation")


cursor.execute(SQLCommand)
data = cursor.fetchone()[0]




image_64_decode = base64.decodebytes(data)
image_result = open('booking.png', 'wb')
image_result.write(image_64_decode)
image_result.close()


connection.close()

The expected result is that I should be able to fetch the bytes from the database which the database column is varbinary(max) the equivalent of bytes in python. once the bytes are fetched using the script in python it should save a file as booking.png which should replicate the image i stored in the database.

When i run the script i don't get an error, and in fact it saves a file, but the file is empty containing 1kb and does not reproduce the image. Not sure where i am going wrong, but it seems like it's not properly fetching the bytes.

Ответы [ 2 ]

0 голосов
/ 09 июля 2019

Нет необходимости в кодировке base64. Если вы используете pyodbc вместо pypyodbc, тогда это так же просто, как

# test data
photo_path = r'C:\Users\Public\Pictures' + '\\'
email = 'bob@example.com'

# test environment
cursor.execute("""\
CREATE TABLE #validation (
    email nvarchar(255) PRIMARY KEY, 
    photo varbinary(max))
""")

# save binary file
with open(photo_path + 'generic_man.jpg', 'rb') as photo_file:
    photo_bytes = photo_file.read()
cursor.execute("INSERT INTO #validation (email, photo) VALUES (?, ?)", email, photo_bytes)
print(f'{len(photo_bytes)}-byte file written for {email}')
# 5632-byte file written for bob@example.com

# retrieve binary data and save as new file
retrieved_bytes = cursor.execute("SELECT photo FROM #validation WHERE email = ?", email).fetchval()
with open(photo_path + 'new.jpg', 'wb') as new_jpg:
    new_jpg.write(retrieved_bytes)
print(f'{len(retrieved_bytes)} bytes retrieved and written to new file')
# 5632 bytes retrieved and written to new file
0 голосов
/ 08 июля 2019

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

Существует только одна проблема - это работает, только если я использую тип данных nvarchar (max) для столбца, в котором хранятся байты изображения. Я получаю ошибки, когда использую varbinary (max) или когда я решаю ошибку, она просто не извлекает укусы и не преобразует их должным образом - любые указания о том, что я могу делать неправильно, поскольку у меня такое ощущение, что это что-то маленькое. Обновленный код ниже - это то, что я делаю, используя работающий nvarchar (max).

import pypyodbc
import base64
from base64 import * 

connection = pypyodbc.connect('Driver=SQL Server;'
                            'Server=DESKTOP-MSSQLSERVER;'
                            'Database=Test;'
                            'Trusted_Connection=yes;'
                            )

cursor = connection.cursor()

a = 'bob@bob.com'
b = 'mack jones'
filename = 'bookingsuccessful.PNG'


image = open(filename, 'rb')
image_read = image.read()
image_64_encode = base64.encodebytes(image_read)


image.close()

SQLCommand = ("INSERT INTO Validation(email, myname, photo) VALUES(?,?,?)")
Values = [a,b,image_64_encode]
cursor.execute(SQLCommand, Values)
connection.commit()

SQLCommand = ("SELECT Photo FROM validation")
cursor.execute(SQLCommand)
data = cursor.fetchone()[0]
data = bytes(data.strip("\n"), 'utf-8')

image_64_decode = base64.decodebytes(data)
image_result = open('testfile.gif', 'wb')
image_result.write(image_64_decode)
image_result.close()

connection.close()
...