Python, Sqlite3 - Как преобразовать список в BLOB-ячейку - PullRequest
9 голосов
/ 11 февраля 2009

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

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

Ответы [ 5 ]

19 голосов
/ 12 февраля 2009

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

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

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

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

Вот некоторые примечания об ограничениях данных BLOB-объектов sqlite:

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

8 голосов
/ 11 февраля 2009

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

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

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

3 голосов
/ 16 декабря 2010

У меня та же проблема, и я подумываю решить ее по-другому.

Я думаю, что модуль pickle сделан именно для чего-то подобного (сериализация на объектах 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" ) )

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

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

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

2 голосов
/ 13 сентября 2009

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

модуль y_serial.py :: хранилище объектов Python с SQLite

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

http://yserial.sourceforge.net

1 голос
/ 13 марта 2013

Можно хранить данные объекта в виде дампов, джаза и т. Д., Но также можно индексировать их, ограничивать и запускать запросы на выборку, использующие эти индексы. Вот пример с кортежами, которые могут быть легко применены для любого другого класса 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...