Pregunta

Quiero almacenar una clave entera en estantería. Pero cuando trato de tienda número entero clave en la estantería me da un error

Traceback (most recent call last):
  File "./write.py", line 12, in 
    data[id] = {"Id": id, "Name": name}
  File "/usr/lib/python2.5/shelve.py", line 124, in __setitem__
    self.dict[key] = f.getvalue()
  File "/usr/lib/python2.5/bsddb/__init__.py", line 230, in __setitem__
    _DeadlockWrap(wrapF)  # self.db[key] = value
  File "/usr/lib/python2.5/bsddb/dbutils.py", line 62, in DeadlockWrap
    return function(*_args, **_kwargs)
  File "/usr/lib/python2.5/bsddb/__init__.py", line 229, in wrapF
    self.db[key] = value
TypeError: Integer keys only allowed for Recno and Queue DB's

Mi código:

#!/usr/bin/python

import shelve

data = shelve.open("data.txt")

ans = 'y'
while ans == "y":
    id = input("Enter Id : ")
    name = raw_input("Enter name : ")

    data[id] = {"Id": id, "Name": name}

    ans = raw_input("Do you want to continue (y/n) ? : ")

data.close()

Hay algo mal en mi programa o dejar de lado no enteros soportes claves en absoluto?


Editar 1:

En el programa estoy tratando de almacenar un diccionario de identificador y el nombre dentro de otro diccionario con identificación como una clave. Y luego tratar de guardarlo en un archivo.

¿Es necesario utilizar RECNO o cola de DB junto con la estantería? Soy un principiante y las cosas son confusas.

Avísame si no me queda claro con mi pregunta.

Gracias.

¿Fue útil?

Solución

El módulo de estantería utiliza un paquete de base de datos subyacente (tal como dbm, gdbm o bsddb).

Una "plataforma" es un persistente, diccionario-como objeto. La diferencia con las bases de datos "DBM" es que los valores (no las llaves!) En un estante pueden ser esencialmente arbitraria objetos Python - cualquier cosa que el módulo pickle puede manejar. Esto incluye la mayoría de las instancias de clase, tipos de datos recursivos, y los objetos que contienen una gran cantidad de sub-objetos compartidos. Las claves son cadenas normales. sección de los ejemplos le da la prueba.

Esto debería funcionar. Esto es lo que hago en mi código -

import shelve

#Create shelve
s = shelve.open('test_shelf.db')
try:
    s['key1'] = { 'int': 10, 'float':9.5, 'string':'Sample data' }
finally:
    s.close()

#Access shelve
s = shelve.open('test_shelf.db')
try:
    existing = s['key1']
finally:
    s.close()
print existing

ACTUALIZACIÓN: Usted podría intentar módulo pickle. No es una base de datos clave-valor, pero siempre se puede construir la estructura de datos como pares de valores clave y luego enviarlo a pickle -

Si usted tiene un objeto x, y un objeto de archivo f que se ha abierto para escritura, la forma más sencilla de estibar el objeto tiene una sola línea de código

pickle.dump(x, f)

Para unpickle el objeto de nuevo, si f es un objeto de archivo que se ha abierto para la lectura:

x = pickle.load(f)

Me cPickle escuchar es mucho más rápido que pickle. Usted puede intentar esto si tiene gran cantidad de datos a almacenar.

Otros consejos

En su ejemplo las llaves en su base de datos será siempre números enteros, por lo que debería funcionar bien para convertirlos en cadenas,

datos [str (id)] = { "id": id, "Nombre": nombre}

mi código de prueba

def shelve_some_data(filename):
    db = shelve.open(filename, flag="c")
    try:
        # note key has to be a string
        db[str(1)]    = "1 integer key that's been stringified" 
        db[str(2)]    = "2 integer key that's been stringified" 
        db[str(3)]    = "3 integer key that's been stringified" 
        db[str(10)]   = "10 integer key that's been stringified" 
    finally:
        db.close()

def whats_in(filename):
    db = shelve.open(filename, flag="r")
    for k in db:
        print("%s : %s" % (k, db[k]))
    return

filename = "spam.db"
shelve_some_data(filename)
whats_in(filename)

Y la salida; funciona como un diccionario así que no es resolver el problema.

2 : 2 integer key that's been stringified
10 : 10 integer key that's been stringified
1 : 1 integer key that's been stringified
3 : 3 integer key that's been stringified
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top