Como faço para tomar teclas inteiras em Shelve?
-
26-09-2019 - |
Pergunta
Eu quero armazenar uma chave inteira em Shelve. Mas quando tento armazenar a chave inteira em Shelve, ela me dê um erro
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
Meu 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()
Algo errado no meu programa ou Shelve não suporta chaves inteiras?
Editar 1:
No programa, estou tentando armazenar um dicionário de identificação e nome dentro de outro dicionário com ID como uma chave. E depois tentando armazená -lo em um arquivo.
Preciso usar o RECNO ou a fila DBs junto com o Shelve? Eu sou iniciante e as coisas são confusas.
Deixe -me saber se não estou claro com minha pergunta.
Obrigado.
Solução
O módulo Shelve usa um pacote de banco de dados subjacente (como DBM, GDBM ou BSDDB).
Uma "prateleira" é um objeto persistente e semelhante ao dicionário. A diferença com os bancos de dados "DBM" é que os valores (não as chaves!) Em uma prateleira podem ser essencialmente objetos de python arbitrários - qualquer coisa que o módulo de pickle possa suportar. Isso inclui a maioria das instâncias de classe, tipos de dados recursivos e objetos contendo muitos subobjetos compartilhados. As chaves são cordas comuns. o exemplos A seção fornece a prova.
Isso deve funcionar. Aqui está o que eu faço no meu 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
ATUALIZAR: Você poderia tentar pickle
módulo. Não é um banco de dados de valor-chave, mas você sempre pode criar sua estrutura de dados como um pares de valor-chave e depois enviá-lo para pickle
-
Se você tem um objeto x e um objeto de arquivo f que foi aberto para escrever, a maneira mais simples de consertar o objeto leva apenas uma linha de código
pickle.dump(x, f)
Para descrever o objeto novamente, se f é um objeto de arquivo que foi aberto para leitura:
x = pickle.load(f)
Eu ouço cPickle
é muito mais rápido do que pickle
. Você pode tentar isso se tiver muitos dados para armazenar.
Outras dicas
No seu exemplo, as chaves no seu banco de dados sempre serão inteiros, por isso deve funcionar bem para convertê -las em strings,
dados [str (id)] = {"id": id, "nome": nome}
Meu código de teste
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)
E a saída; Funciona como um ditado, para que não seja resolvido.
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