open how python sqlite pickle

how - pickle python stack



¿Puedo extraer un diccionario de Python en un campo de texto sqlite3? (13)

Como Pickle puede volcar el gráfico de objetos a una cadena, debería ser posible.

Sin embargo, tenga en cuenta que los campos TEXT en SQLite usan codificación de base de datos, por lo que es posible que necesite convertirlo a una cadena simple antes de desasignar.

¿Algún problema que deba tener en cuenta? ¿Puedo guardarlo en un campo de texto o necesito usar un blob? (No estoy demasiado familiarizado ni con pickle ni con sqlite, así que quería asegurarme de estar ladrando al árbol correcto con algunas de mis ideas de diseño de alto nivel).


Dependiendo de en qué esté trabajando, es posible que desee examinar el módulo shove . Hace algo similar, donde auto-almacena objetos Python dentro de una base de datos sqlite (y todo tipo de otras opciones) y pretende ser un diccionario (al igual que el módulo shelve ).


Es posible almacenar datos de objeto como pickle dump, jason, etc., pero también es posible indexarlos, restringirlos y ejecutar consultas selectas que usen esos índices. Aquí hay un ejemplo con tuplas, que se puede aplicar fácilmente para cualquier otra clase de python. Todo lo que se necesita se explica en la documentación de python sqlite3 (alguien ya publicó el enlace). De todos modos aquí está todo armado en el siguiente ejemplo:

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("explain query plan select p from test where p > ?", ((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()


Escribí un blog sobre esta idea, excepto que en lugar de un pickle, utilicé json, ya que quería que fuera interoperable con Perl y otros programas.

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

Arquitectónicamente, esta es una manera rápida y sucia de obtener persistencia, transacciones y similares para estructuras de datos arbitrarias. He encontrado que esta combinación es realmente útil cuando quiero persistencia, y no necesito hacer mucho en la capa sql con los datos (o es muy compleja de tratar en sql, y simple con generadores).

El código en sí es bastante simple:

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

Entonces, cuando quieras volcarlo en el db,

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


La otra opción, teniendo en cuenta que su requisito es guardar un dict y luego escupirlo para el "placer de visualización" del usuario, es usar el módulo shelve que le permitirá conservar cualquier archivo de datos recolector. Los documentos de Python están here .


Necesitaba lograr lo mismo también.

Resultó que me causó un gran dolor de cabeza antes de que finalmente me diera cuenta, gracias a esta publicación , de cómo hacer que funcione en un formato binario.

Para insertar / actualizar:

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

Debe especificar el segundo argumento para volcar para forzar un decapado binario.
También tenga en cuenta el sqlite3.Binary para que quepa en el campo BLOB.

Para recuperar datos:

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

Al recuperar un campo BLOB, sqlite3 obtiene un tipo de pitón ''buffer'', que necesita ser strinfied usando str antes de pasar al método de cargas.


Pickle tiene formatos de texto y de salida binarios. Si utiliza el formato basado en texto, puede almacenarlo en un campo TEXTO, pero tendrá que ser un BLOB si usa el formato binario (más eficiente).


Sí, puede almacenar un objeto escabechado en un campo TEXTO o BLOB en una base de datos SQLite3, como otros han explicado.

Solo tenga en cuenta que algunos objetos no pueden ser escabechados . Los tipos de contenedores incorporados pueden (dict, set, list, tuple, etc.). Pero algunos objetos, como los identificadores de archivos, hacen referencia al estado que es externo a sus propias estructuras de datos, y otros tipos de extensiones tienen problemas similares.

Como un diccionario puede contener estructuras de datos anidadas arbitrarias, es posible que no sea seleccionable.


Si desea almacenar un objeto escabechado, deberá usar un blob, ya que se trata de datos binarios. Sin embargo, puede, por ejemplo, base64 codificar el objeto escabechado para obtener una cadena que pueda almacenarse en un campo de texto.

En general, sin embargo, hacer este tipo de cosas es indicativo de un mal diseño, ya que estás almacenando datos opacos, pierdes la capacidad de usar SQL para realizar cualquier manipulación útil sobre esos datos. Aunque sin saber lo que estás haciendo realmente, no puedo realmente hacer un llamado moral sobre él.


Si un diccionario se puede escalar, también se puede almacenar en el campo de texto / blob.

Solo tenga en cuenta los diccionarios que no pueden ser escabechados (es decir, que contienen objetos que no se pueden pinchar).


SpoonMeiser es correcto, debe tener una buena razón para guardar una base de datos.

No es difícil escribir objetos Python que implementen persistencia con SQLite. Luego puede usar la CLI de SQLite para alterar los datos también. Lo cual en mi experiencia vale la pena el trabajo extra, ya que muchas funciones de depuración y administración se pueden realizar simplemente desde la CLI en lugar de escribir código Python específico.

En las primeras etapas de un proyecto, hice lo que propones y terminé reescribiendo con una clase de Python para cada objeto comercial (nota: ¡no lo dije en cada tabla!) De esta manera, el cuerpo de la aplicación puede enfocarse en "qué" debe hacerse en lugar de "cómo" se hace.


Tengo que estar de acuerdo con algunos de los comentarios aquí. Tenga cuidado y asegúrese de que realmente desea guardar los datos de pickle en una base de datos, probablemente haya una mejor manera.

En cualquier caso, tuve problemas en el pasado tratando de guardar datos binarios en el sqlite db. Aparentemente tienes que usar el sqlite3.Binary () para preparar los datos para sqlite.

Aquí hay un código de muestra:

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


Vea esta solución en SourceForge:

y_serial.py module :: warehouse Python objects with SQLite

"Serialización + persistencia :: en unas pocas líneas de código, comprima y anote objetos de Python en SQLite, y luego recupérelos cronológicamente por palabras clave sin ningún SQL. Módulo" estándar "más útil para que una base de datos almacene datos sin esquema".

http://yserial.sourceforge.net