Сохранение кортежей как типов данных BLOB-объектов в Sqlite3 в Python - PullRequest
0 голосов
/ 10 марта 2011

У меня есть словарь на python. Их ключи - это кортежи с переменным размером, содержащие символы Юникода, а значения - это просто одно целое число. Я хочу вставить этот словарь в sqlite db с таблицей из 2 столбцов.

Первый столбец предназначен для значений ключа, а второй столбец должен иметь соответствующее значение типа int. Почему я хочу это сделать? у меня очень большой словарь, и я использовал cPickle, даже установив протокол на 2. Размер все еще большой, а сохранение и загрузка этого файла занимают много времени. Поэтому я решил сохранить его в БД. Этот словарь загружается в память только один раз в начале программы, поэтому дополнительная операция не выполняется.

Теперь проблема в том, что я хочу сохранить кортежи точно в виде кортежей (не строк), поэтому всякий раз, когда я загружаю свою таблицу в память, я могу без проблем создавать свой словарь. Кто-нибудь знает, как я могу это сделать?

Ответы [ 3 ]

3 голосов
/ 10 марта 2011

Пара вещей. Во-первых, SQLite не позволяет напрямую хранить структуры данных Python. Во-вторых, я предполагаю, что вы хотите иметь возможность запрашивать значение по ключу кортежа по требованию, поэтому вы не хотите выбирать и открывать, а затем искать ключи в диктовке.

Проблема в том, что вы не можете делать запросы с кортежами и не можете разбить записи кортежей на их собственные столбцы, потому что они имеют разные размеры. Если вы должны использовать SQLite, вам в значительной степени придется объединять символы юникода в кортеже, возможно, с разделителем, который не является одним из символов в значениях кортежа. Используйте его в качестве ключа и сохраните в столбце SQLite в качестве столбца первичного ключа.

def tuple2key(t, delimiter=u':'):
    return delimiter.join(t)

import sqlite3

conn = sqlite3.connect('/path/to/your/db')
cur = conn.cursor()

cur.execute('''create table tab (k text primary key, value integer)''')

# store the dict into a table
for k, v in my_dict.iteritems():
    cur.execute('''insert into tab values (?, ?)''', (tuple2key(k), v))

cur.commit()

# query the values
v = cur.execute(''' select value from tab where key = ? ''', tuple2key((u'a',u'b'))).fetchone()
2 голосов
/ 10 сентября 2014

Можно хранить кортежи в sqlite db и создавать индексы для кортежей.Для этого нужен дополнительный код.Является ли хранение кортежей в db подходящим решением в данном конкретном случае - это еще одна проблема (возможно, лучше подходит решение с двумя ключами).

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))

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)")

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

cur.execute("insert into test(p) values (?)", (p,))
cur.execute("insert into test(p) values (?)", (p1,))

#ordered select
cur.execute("select p from test order by p collate cmptuple")
0 голосов
/ 10 марта 2011

Я думаю, что лучше создать 3 столбца в вашей таблице - key1, key2 и value.

Если вы предпочитаете сохранить ключ как кортеж, вы все равно можете использовать pickle, но применять только к ключу,Затем вы можете сохранить его как BLOB-объект.

>>> pickle.dumps((u"\u20AC",u"\u20AC"))
'(V\\u20ac\np0\ng0\ntp1\n.'
>>> pickle.loads(_)
(u'\u20ac', u'\u20ac')
>>>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...