Python, Sqlite3-как преобразовать список в ячейку BLOB

каков самый элегантный метод для сброса списка в python в sqlite3 DB в качестве двоичных данных (т. е. ячейки BLOB)?

data = [ 0, 1, 2, 3, 4, 5 ]
# now write this to db as binary data
# 0000 0000
# 0000 0001
# ...
# 0000 0101

5 ответов


предполагая, что вы хотите, чтобы он рассматривался как последовательность 8-битных значений без знака, используйте array модуль.

a = array.array('B', data)
>>> a.tostring()
'\x00\x01\x02\x03\x04\x05'

использовать различные typecodes, чем 'B' Если вы хотите обрабатывать данные разных типов. например. "b" для последовательности подписанных байтов или 'i' для целого числа со знаком.


Кажется, что решение Брайана соответствует вашим потребностям, но имейте в виду, что с помощью этого метода вы просто храните данные в виде строки.

Если вы хотите сохранить необработанные двоичные данные в базе данных (чтобы это не занимало столько места), преобразуйте свои данные в Бинарные объект sqlite, а затем добавьте его в свою базу данных.

query = u'''insert into testtable VALUES(?)'''
b = sqlite3.Binary(some_binarydata)
cur.execute(query,(b,))
con.commit()

(по какой-то причине это, похоже, не задокументировано в документации python)

вот некоторые заметки о ограничения данных SQLite BLOB:

http://effbot.org/zone/sqlite-blob.htm


у меня такая же проблема, и я думаю о решении этого по-другому.

Я думаю огурец модуль сделан именно для чего-то подобного (сериализация на объектах python)

пример (это для сброса в файл... но я думаю, что это легко изменить для хранения БД)

экономия:

# Save a dictionary into a pickle file.
import pickle
favorite_color = { "lion": "yellow", "kitty": "red" }
pickle.dump( favorite_color, open( "save.p", "w" ) )

нагрузка:

# Load the dictionary back from the pickle file.
import pickle
favorite_color = pickle.load( open( "save.p" ) )

IMHO я думаю, что этот способ более элегантный и безопасный(он работает для любого python объект.)

это мои 2 цента

обновление: после небольшого поиска по моей идее, они показывают некоторые gotchas на моем решении (я не могу сделать SQL-поиск в этом поле). Но я все еще думаю, что это достойное решение (если вам не нужно искать это поле.


см. это общее решение в SourceForge, которое охватывает любой произвольный объект Python (включая список, кортеж, словарь и т. д.):

y_serial.py модуль:: складские объекты Python с SQLite

"сериализация + сохранение :: в нескольких строках кода сжимайте и аннотируйте объекты Python в SQLite; затем извлекайте их хронологически по ключевым словам без SQL. Самый полезный" стандартный " модуль для базы данных для хранения без схемы данные."

http://yserial.sourceforge.net


можно хранить данные объекта в виде дампа рассола, jason и т. д., но также можно индексировать их, ограничивать их и запускать запросы select, которые используют эти индексы. Вот пример с кортежами, которые можно легко применить для любого другого класса python. Все, что нужно, объясняется в документации python sqlite3 (кто-то уже разместил ссылку). Во всяком случае, здесь все это собрано в следующем примере:

import sqlite3
import pickle

def adapt_tuple(tuple):
    return pickle.dumps(tuple)    

sqlite3.register_adapter(tuple, adapt_tuple)    #cannot use pickle.dumps directly because of inadequate argument signature 
sqlite3.register_converter("tuple", pickle.loads)

def collate_tuple(string1, string2):
    return cmp(pickle.loads(string1), pickle.loads(string2))

#########################
# 1) Using declared types
con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)

con.create_collation("cmptuple", collate_tuple)

cur = con.cursor()
cur.execute("create table test(p tuple unique collate cmptuple) ")
cur.execute("create index tuple_collated_index on test(p collate cmptuple)")

cur.execute("select name, type  from sqlite_master") # where type = 'table'")
print(cur.fetchall())

p = (1,2,3)
p1 = (1,2)

cur.execute("insert into test(p) values (?)", (p,))
cur.execute("insert into test(p) values (?)", (p1,))
cur.execute("insert into test(p) values (?)", ((10, 1),))
cur.execute("insert into test(p) values (?)", (tuple((9, 33)) ,))
cur.execute("insert into test(p) values (?)", (((9, 5), 33) ,))

try:
    cur.execute("insert into test(p) values (?)", (tuple((9, 33)) ,))
except Exception as e:
    print e

cur.execute("select p from test order by p")
print "\nwith declared types and default collate on column:"
for raw in cur:
    print raw

cur.execute("select p from test order by p collate cmptuple")
print "\nwith declared types collate:"
for raw in cur:
    print raw

con.create_function('pycmp', 2, cmp)

print "\nselect grater than using cmp function:"
cur.execute("select p from test where pycmp(p,?) >= 0", ((10, ),) )
for raw in cur:
    print raw

cur.execute("select p from test where pycmp(p,?) >= 0", ((3,)))
for raw in cur:
    print raw 

print "\nselect grater than using collate:"
cur.execute("select p from test where p > ?", ((10,),) )
for raw in cur:
    print raw  

cur.execute("explain query plan select p from test where p > ?", ((3,)))
for raw in cur:
    print raw

cur.close()
con.close()