كيف أتناول مفاتيح عدد صحيح في الرف؟
-
26-09-2019 - |
سؤال
أريد تخزين مفتاح عدد صحيح في الرف. لكن عندما أحاول تخزين مفتاح عدد صحيح في الرفوف ، فإنه يعطيني خطأ
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
رمز بلدي :
#!/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()
هل هناك شيء خاطئ في برنامجي أو الرفوف لا يدعم مفاتيح عدد صحيح على الإطلاق؟
تحرير 1:
في البرنامج أحاول تخزين قاموس الهوية والاسم داخل قاموس آخر مع معرف كمفتاح. ثم محاولة تخزينه في ملف.
هل أحتاج إلى استخدام Recno أو قائمة الانتظار DB مع Shelve؟ أنا مبتدئ والأشياء مربكة.
اسمحوا لي أن أعرف إذا لم أكن واضحا مع سؤالي.
شكرًا.
المحلول
تستخدم وحدة LESVE حزمة قاعدة بيانات أساسية (مثل DBM أو GDBM أو BSDDB).
"الرف" هو كائن مستمر يشبه القاموس. الفرق في قواعد بيانات "DBM" هو أن القيم (وليس المفاتيح!) في الرف يمكن أن تكون كائنات بيثون تعسفية بشكل أساسي - أي شيء يمكن أن تتعامل معه وحدة المخلل. يتضمن ذلك معظم مثيلات الفصل وأنواع البيانات المتكررة والكائنات التي تحتوي على الكثير من الكائنات الفرعية المشتركة. المفاتيح سلاسل عادية. ال أمثلة يمنحك القسم الدليل.
هذا يجب أن يعمل. هذا ما أفعله في الكود الخاص بي -
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
تحديث: بامكانك ان تحاول pickle
وحدة. إنها ليست قاعدة بيانات ذات قيمة رئيسية ولكن يمكنك دائمًا إنشاء بنية البيانات الخاصة بك كأزواج ذات قيمة رئيسية ثم إرسالها إلى pickle
-
إذا كان لديك كائن x ، وكائن ملف f الذي تم فتحه للكتابة ، فإن أبسط طريقة لمخلل الكائن يأخذ سطرًا واحدًا فقط من التعليمات البرمجية
pickle.dump(x, f)
لفك الكائن مرة أخرى ، إذا كان F هو كائن ملف تم فتحه للقراءة:
x = pickle.load(f)
أنا أسمع cPickle
أسرع بكثير من pickle
. يمكنك تجربة هذا إذا كان لديك الكثير من البيانات لتخزينها.
نصائح أخرى
في مثالك ، ستكون المفاتيح الموجودة في قاعدة البيانات الخاصة بك دائمًا أعداد صحيحة ، لذلك يجب أن تعمل بشكل جيد لتحويلها إلى سلاسل ،
Data [str (id)] = {"id": id ، "name": name}
رمز الاختبار الخاص بي
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)
والإخراج ؛ إنه يعمل مثل القولان حتى لا يتم فرزه.
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