【问题标题】:Shelve module in python not working: "db type cannot be determined"python中的搁置模块不起作用:“无法确定数据库类型”
【发布时间】:2013-05-18 06:46:01
【问题描述】:

我正在尝试用 Python 制作一个简单的密码存储程序,它看起来很简单,所以我想知道我是否使用 shelve 错误。

我有主 .py 文件:

import shelve

passwords = shelve.open('./passwords_dict.py')

choice = raw_input("Add password (a) or choose site (c)?")

if choice[0] == 'a':
    site_key = raw_input("Add for which site? ").lower()
    userpass = raw_input("Add any info such as username, email, or passwords: ")

    passwords[site_key] = userpass

else:
    site = raw_input("Which site? ").lower()
    if site in passwords:
        print "Info for " + site + ": " + passwords[site]
    else:
        print site, "doesn't seem to exist!"

print "Done!"

passwords.close()

而另一个文件,passwords_dict.py,只是一个空字典。

但是当我尝试运行程序时,我得到了这个错误:

Traceback (most recent call last):
File "passwords.py", line 3, in <module>
passwords = shelve.open('passwords_dict.py')
File "/usr/lib/python2.7/shelve.py", line 239, in open
return DbfilenameShelf(filename, flag, protocol, writeback)
File "/usr/lib/python2.7/shelve.py", line 223, in __init__
Shelf.__init__(self, anydbm.open(filename, flag), protocol, writeback)
File "/usr/lib/python2.7/anydbm.py", line 82, in open
raise error, "db type could not be determined"
anydbm.error: db type could not be determined

当我尝试改用 anydbm 时,我收到此错误:

Traceback (most recent call last):
File "passwords.py", line 3, in <module>
passwords = anydbm.open('passwords_dict.py')
File "/usr/lib/python2.7/anydbm.py", line 82, in open
raise error, "db type could not be determined"
anydbm.error: db type could not be determined

当我尝试改用 dbm 时,我得到了这个错误:

Traceback (most recent call last):
File "passwords.py", line 3, in <module>
passwords = dbm.open('./passwords_dict.py')
dbm.error: (2, 'No such file or directory')

我做错了什么?是否有另一种存储字典的方法,并且仍然能够使用用户输入提取键(而不是整个字典,我想这就是 pickle 所做的)?

【问题讨论】:

    标签: python python-2.7 persistent-storage shelve dbm


    【解决方案1】:

    我认为您误解了搁置模块的工作原理。它打开一个数据库文件。当您尝试打开包含 Python 脚本的现有文件时,它会尝试检测文件包含的数据库类型(因为 shelve 支持多个后端数据库)。

    我认为你想要这样的东西:

    import os
    import shelve
    
    curdir = os.path.dirname(__file__)
    passwords = shelve.open(os.path.join(curdir, 'password_db'))
    

    这将在与您的脚本相同的目录中创建一个名为password_db.&lt;db&gt; 的新文件,其中&lt;db&gt; 是特定于实现的数据库文件扩展名。

    【讨论】:

      【解决方案2】:

      我也遇到过这个问题。它似乎与shelve.openfilename 参数的未记录条件有关。它目前非常不透明(例如 shelve.open("/tmp/tmphTTQLda") 有效,而 shelve.open("/tmp/tmphTTQLd") 无效)。变量文件名的失败和成功很难预测。我要求在http://bugs.python.org/issue23174 以文档增强的形式进行解释。

      在我的情况下,在shelve 之外打开一个持久性字典并将其传递给shelve.Shelve 可以工作,例如代码

      a = dumbdbm.open(tempfile.mkstemp()[1])
      b = shelve.Shelf(dict=a)
      

      然后用b 做你对shelve.open 的返回值所做的事情。

      【讨论】:

      • 抱歉,它的临时文件是什么?如果临时文件已经存在,这也有效?
      • tempfile 是一个标准的 Python 模块。 tempfile.mkstemp 应该根据定义创建一个不存在的文件。
      【解决方案3】:

      anydb https://bugs.python.org/issue13007 存在一个错误,无法为 gdbm 文件使用正确的标识。

      因此,如果您尝试使用 shelve 打开一个有效的 gdbm 文件并且正在解决该错误,请改用它:

          mod = __import__("gdbm")
          file = shelve.Shelf(mod.open(filename, flag))
      

      关于这个问题的更多信息:shelve db type could not be determined, whichdb is not recognizing gdb

      【讨论】:

      • 为什么不只是import gdbm,然后是file = shelve.Shelf(gdbm.open(filename, flag)),这似乎更像是pythonic?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-20
      • 1970-01-01
      • 1970-01-01
      • 2019-06-03
      • 2021-10-06
      相关资源
      最近更新 更多