Вставить двоичный файл в базу данных SQLite с помощью Python
Я пытаюсь написать простой Python script, который вставляет .odt документы в базу данных SQLite. Вот что я сделал до сих пор, но, похоже, это не работает:
f=open('Loremipsum.odt', 'rb')
k=f.read()
f.close()
cursor.execute="INSERT INTO notes (note) VALUES ('%s')" %(sqlite.Binary(k))
cursor.close()
conn.close()
Я не получаю никаких сообщений об ошибках, но насколько я вижу, запись не вставлена. Что я делаю не так? Кроме того, как я могу извлечь сохраненный документ? Спасибо!
Ответы
Ответ 1
Не уверен, что это такое sqlite.Binary
, которое вы используете, но, во всяком случае, здесь рабочий пример:
import sqlite3
# let just make an arbitrary binary file...
with open('/tmp/abin', 'wb') as f:
f.write(''.join(chr(i) for i in range(55)))
# ...and read it back into a blob
with open('/tmp/abin', 'rb') as f:
ablob = f.read()
# OK, now for the DB part: we make it...:
db = sqlite3.connect('/tmp/thedb')
db.execute('CREATE TABLE t (thebin BLOB)')
db.execute('INSERT INTO t VALUES(?)', [buffer(ablob)])
db.commit()
db.close()
# ...and read it back:
db = sqlite3.connect('/tmp/thedb')
row = db.execute('SELECT * FROM t').fetchone()
print repr(str(row[0]))
При запуске с Python 2.6 этот код показывает, как ожидалось и желательно: "\ X00\x01\x02\x03\x04\x05\x06\X07\x08\т\п\x0b\x0c\г\x0e\X0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f!" # $% &\'() * +, -./0123456'
Обратите внимание на необходимость использования buffer
, чтобы вставить blob, и str
, чтобы прочитать его как строку (поскольку в качестве результата он также использует тип buffer
) - если вы просто собираетесь чтобы записать его на диск, последний проход не понадобился (так как метод write
файлов принимает объекты буфера так же хорошо, как принимает строки).
Ответ 2
Проблемы:
-
Вы не указали полный код, который вы использовали. Вы не должны оставлять ответчиков, угадывая, что такое sqlite.Binary(k)
.
-
Основная проблема: вы не совершали транзакции. Используйте conn.commit()
до conn.close()
.
Ответ 3
В данном примере существует несколько проблем. я буду
обращайтесь к ним один за другим.
- Проверка ошибок отсутствует. Нам либо нужно использовать try/except/finally
построить или использовать ключевое слово с.
- Методы Python не похожи на свойства С#. Вы не используете метод
execute()
, вы назначаете некоторую строку объекту. (В Python методы тоже являются объектами.)
- Очень важно, чтобы ваш код подвергался атакам SQL Injection. Мы никогда не должны создавать инструкции SQL, используя строковые операции Python. Мы всегда должны использовать заполнители.
- Пример неполный. Это приводит к сложной проблеме. Предположим, что существует инструкция
CREATE TABLE
, тогда будет создана новая неявная транзакция. А для вывода данных в файл базы данных должен быть выдан оператор commit()
. В SQLite любой оператор, отличный от SELECT
, запускает неявную транзакцию. (Некоторые базы данных, такие как MySQL, по умолчанию работают в режиме autocommit. Это не относится к SQLite.)
Вот правильный рабочий пример, который будет записывать документ LibreOffice в Документы
таблица базы данных SQLite:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sqlite3 as lite
fl = open('book.odt', 'rb')
with fl:
data = fl.read()
con = lite.connect('test.db')
with con:
cur = con.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS Docs(Data BLOB)")
sql = "INSERT INTO Docs(Data) VALUES (?)"
cur.execute(sql, (lite.Binary(data), ))
Файл book.odt находится в текущем рабочем каталоге. Мы не вызывали метод commit() вручную, так как это обрабатывается ключевым словом "за кулисами".