Как взять целочисленные ключи на полке? - PullRequest
2 голосов
/ 25 октября 2010

Я хочу хранить целочисленный ключ на полке.Но когда я пытаюсь сохранить целочисленный ключ в полке, он выдает ошибку

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:

В программе я пытаюсь сохранить словарь Id и Name в другом словаре с Idв качестве ключа.А затем пытается сохранить его в файле.

Нужно ли использовать Recno или Queue DB вместе с полкой?Я новичок, и все сбивает с толку.

Дайте мне знать, если мне не ясен мой вопрос.

Спасибо.

Ответы [ 2 ]

1 голос
/ 06 июля 2018

В вашем примере ключи в вашей базе данных всегда будут целыми числами, поэтому он должен нормально работать для преобразования их в строки,

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
0 голосов
/ 25 октября 2010

Модуль shelve использует базовый пакет базы данных (например, dbm, gdbm или bsddb).

"Полка" - это постоянный словарный объект. Разница с базами данных "dbm" заключается в том, что значения (а не ключи!) В полке могут быть по существу произвольными объектами Python - всем, что может обрабатывать модуль pickle. Это включает в себя большинство экземпляров классов, рекурсивных типов данных и объектов, содержащих множество общих подобъектов. Ключи обычные струны. Раздел examples дает вам подтверждение.

Это должно работать. Вот что я делаю в своем коде -

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. Вы можете попробовать это, если у вас есть много данных для хранения.

...