Я могу засолить словарь Python в sqlite3 текстовое поле?

Этот вопрос представляет собой немного часто задаваемых вопросов, поэтому я публикую это как wiki (так как раньше я писал аналогично, но это более старый); в любом случае ...

Какую версию .NET вы используете? Если вы используете .NET 3.5, то у меня есть реализация общих операторов в MiscUtil (бесплатно и т. Д.).

У этого есть методы, такие как T Add(T x, T y) , и другие варианты арифметики для разных типов (например, DateTime + TimeSpan).

Кроме того, это работает для всех встроенных, снятых и сделанных на заказ операторов и кэширует делегат для выполнения.

Некоторые дополнительные сведения о том, почему это сложно, это здесь .

Вы также можете знать, что метод dynamic (4.0) также разрешает эту проблему косвенно, т. Е.

dynamic x = ..., y = ...
dynamic result = x + y; // does what you expect

37
задан Noah 13 February 2009 в 15:00
поделиться

12 ответов

Если Вы захотите хранить соленый объект, необходимо будет использовать блоб, так как это - двоичные данные. Однако Вы можете, скажем, base64 кодировать соленый объект получить строку, которая может быть сохранена в текстовом поле.

Обычно, хотя, делая этот вид вещи показательно из плохого дизайна, так как Вы храните непрозрачные данные, Вы теряете способность использовать SQL, чтобы сделать любое полезное управление на тех данных. Хотя, не зная, что Вы на самом деле делаете, я не могу действительно сделать моральный запрос к нему.

19
ответ дан SpoonMeiser 17 November 2019 в 21:38
поделиться

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

http://writeonly.wordpress.com/2008/12/05/simple-object-db-using-json-and-python-sqlite/

Архитектурно, это - быстрый и грязный способ получить персистентность, транзакции, и т.п. для произвольных структур данных. Я нашел, что эта комбинация действительно полезна, когда я хочу персистентность и не должен делать многого в sql слое с данными (или это очень сложно для контакта с в sql, и простой с генераторами).

сам код довольно прост:

#  register the "loader" to get the data back out.
sqlite3.register_converter("pickle", cPickle.loads) 

Затем когда Вы хотите вывести его в дб,

p_string = p.dumps( dict(a=1,b=[1,2,3]))  
conn.execute(''' 
   create table snapshot( 
      id INTEGER PRIMARY KEY AUTOINCREMENT, 
        mydata pickle); 
''')  

conn.execute(''' 
    insert into snapshot values 
    (null, ?)''', (p_string,))
''')
7
ответ дан rpanai 17 November 2019 в 21:38
поделиться

Рассол имеет и текст и форматы двоичного выхода. При использовании основанного на тексте формата, можно сохранить его в Текстовом поле, но это должен будет быть BLOB при использовании (более эффективного) двоичного формата.

3
ответ дан John Millikin 17 November 2019 в 21:38
поделиться

Так как Рассол может вывести Ваш граф объектов к строке, это должно быть возможно.

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

2
ответ дан Morten Holdflod Møller 17 November 2019 в 21:38
поделиться

Если словарь может быть соле, он может быть сохранен в поле текста/блоба также.

Просто знать о словарях, которые не могут быть солеы (иначе, которые содержат unpickable объекты).

2
ответ дан kender 17 November 2019 в 21:38
поделиться

Да, можно хранить соленый объект в ТЕКСТЕ или поле BLOB в базе данных SQLite3, как другие объяснили.

Просто знать, что некоторый объект не может быть соле . Встроенные контейнерные типы могут (dict, устанавливать, перечислять, кортеж, и т.д.). Но некоторые объекты, такие как дескрипторы файлов, относятся, чтобы указать, что это является внешним к их собственным структурам данных, и другие дополнительные типы имеют подобные проблемы.

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

2
ответ дан Dan Lenski 17 November 2019 в 21:38
поделиться

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

В любом случае я испытал затруднения при прошлой попытке сохранить двоичные данные в sqlite дб. По-видимому, необходимо использовать sqlite3. Двоичный файл () для подготовления данных к sqlite.

Вот некоторый пример кода:

query = u'''insert into testtable VALUES(?)'''
b = sqlite3.Binary(binarydata)
cur.execute(query,(b,))
con.commit()
2
ответ дан monkut 17 November 2019 в 21:38
поделиться

SpoonMeiser корректен, у Вас должна быть веская причина засолить в базу данных.

не трудно записать, что Python возражает что персистентность реализации с SQLite. Тогда можно использовать CLI SQLite для игры с данными также. Который, по моему опыту, стоит дополнительного бита работы, так как многие отлаживают, и функции администрирования могут быть просто выполнены от CLI вместо того, чтобы писать определенный код Python.

На ранних стадиях проекта, я сделал то, что Вы предлагаете и закончили тем, что переписали с классом Python для каждого бизнес-объекта (примечание: Я не сказал для каждой таблицы!) Этот способ, которым тело приложения может сфокусироваться на том, "какие" потребности быть сделанным, а не "как" это сделано.

1
ответ дан CyberFonic 17 November 2019 в 21:38
поделиться

Другая опция, полагая, что Ваше требование должно сохранить dict и затем плюнуть им, отступает для "просмотра пользователя удовольствия", должен использовать shelve модуль, который позволит Вам сохранить любые pickleable данные в файл. Документы Python здесь .

1
ответ дан mhawke 17 November 2019 в 21:38
поделиться

В зависимости от того, что Вы продолжаете работать, Вы могли бы хотеть изучить толчок модуль. Это делает что-то подобное, где это автохранит объекты Python в sqlite базе данных (и все виды других опций) и симулирует быть словарем (точно так же, как эти откладывают модуль).

1
ответ дан Matthew 17 November 2019 в 21:38
поделиться

См. Это решение на SourceForge:

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

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

http://yserial.sourceforge.net

0
ответ дан 27 November 2019 в 04:23
поделиться

Мне тоже нужно было добиться того же самого.

Оказалось, что это вызвало у меня довольно сильную головную боль, прежде чем я наконец понял, благодаря этому посту, как заставить это работать в двоичном формате.

Чтобы вставить/обновить:

pdata = cPickle.dumps(data, cPickle.HIGHEST_PROTOCOL)
curr.execute("insert into table (data) values (:data)", sqlite3.Binary(pdata))

Вы должны указать второй аргумент для дампов, чтобы заставить их работать в бинарном формате.
Также обратите внимание на sqlite3.Binary, чтобы данные помещались в поле BLOB.

Для извлечения данных:

curr.execute("select data from table limit 1")
for row in curr:
  data = cPickle.loads(str(row['data']))

При извлечении BLOB-поля sqlite3 получает python-тип 'buffer', который должен быть расслоен с помощью str перед передачей в метод loads.

47
ответ дан 27 November 2019 в 04:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: