¿Cómo tomo entero llaves en estantería?
-
26-09-2019 - |
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.
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