Wie nehme ich integer Schlüssel in shelve?
-
26-09-2019 - |
Frage
Ich möchte einen Integer-Schlüssel in shelve speichern. Aber wenn ich zum Speichern von Integer-Schlüssel in shelve versuchen, es gib mir einen Fehler
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
Mein Code:
#!/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()
Ist etwas falsch in meinem Programm oder shelve nicht unterstützt ganzzahlige Schlüssel überhaupt?
Bearbeiten 1:
Im Programm Ich versuche, in einem anderen Wörterbuch mit Id ein Wörterbuch von Id und Namen zu speichern als Schlüssel. Und dann versuchen, es in einer Datei zu speichern.
Benötige ich Recno oder Queue DB zusammen mit shelve zu bedienen? Ich bin ein Anfänger und die Dinge sind verwirrend.
Lassen Sie mich wissen, wenn ich nicht mit meiner Frage löschen.
Danke.
Lösung
Das shelve Modul verwendet ein zugrunde liegendes Datenbankpaket (wie dbm, gdbm oder bsddb).
A "Regal" ist eine persistent, Wörterbuch-ähnliches Objekt. Der Unterschied zu „dbm“ Datenbanken ist, dass die Werte (nicht die Tasten!) In einem Regal im wesentlichen beliebig sein können Python-Objekte - etwas, dass die Gurke Modul umgehen kann. Dazu gehören die meisten Klasseninstanzen, rekursiven Datentypen und Objekte viele gemeinsam genutzte Unterobjekte enthält. Die Tasten sind gewöhnliche Saiten. Die Beispiele Abschnitt gibt Ihnen den Beweis.
Das sollte funktionieren. Hier ist, was ich in meinem Code zu tun -
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
UPDATE: Sie könnten pickle
Modul versuchen. Es ist nicht eine Schlüssel-Wert-Datenbank, aber Sie können Ihre Datenstruktur als Schlüssel-Wert-Paare immer bauen und sie dann an pickle
senden -
Wenn Sie ein Objekt x, und ein Dateiobjekt f, die zum Schreiben geöffnet worden sind, der einfachste Weg, um das Objekt zu beizen dauert nur eine Zeile Code
pickle.dump(x, f)
das Objekt wieder unpickle, wenn f ein Dateiobjekt ist, die zum Lesen geöffnet wurden:
x = pickle.load(f)
Ich höre cPickle
ist viel schneller als pickle
. Sie können dies versuchen, wenn Sie viele Daten zu speichern sind.
Andere Tipps
In Ihrem Beispiel der Schlüssel in Ihrer Datenbank werden immer ganze Zahlen sein, so dass es gut funktionieren soll sie in Strings zu konvertieren,
data [str (id)] = { "id": id, "Name": Name}
Mein Testcode
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)
Und die Ausgabe; es funktioniert wie ein dict so ist es nicht sortiert.
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