最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - How do I prevent shelve module from appending ".db" to filename? - Stack Overflow

programmeradmin0浏览0评论

Python: 3.12.2, OS: MacOS 13.6.6

When I specify a filename to shelve.open, it appends .db to the filename:

% ls

% python
Python 3.12.2 (main, Feb  6 2024, 20:19:44) [Clang 15.0.0 (clang-1500.1.0.2.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import shelve
>>> with shelve.open("myfile"):
...     pass
... 
>>> quit()

% ls
myfile.db

Furthermore, if I attempt to open an existing file as "myfile.db" (with the extension), I get the following error:

% python
Python 3.12.2 (main, Feb  6 2024, 20:19:44) [Clang 15.0.0 (clang-1500.1.0.2.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import shelve
>>> with shelve.open("myfile.db"):
...     pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/homebrew/Cellar/[email protected]/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/shelve.py", line 243, in open
    return DbfilenameShelf(filename, flag, protocol, writeback)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/shelve.py", line 227, in __init__
    Shelf.__init__(self, dbm.open(filename, flag), protocol, writeback)
                         ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/dbm/__init__.py", line 89, in open
    raise error[0]("db type could not be determined")
dbm.error: db type could not be determined

Opening the existing file as simply "myfile" with no extension works fine, however.

  1. How do I prevent shelve.open from appending ".db" to the filename?
  2. Why can't I open existing databases if I specify their ".db" extension?

Neither of these issues happen on Python 3.10.12 on Ubuntu 22, so I'm not sure if it's a Python version thing, or a platform thing.

Python: 3.12.2, OS: MacOS 13.6.6

When I specify a filename to shelve.open, it appends .db to the filename:

% ls

% python
Python 3.12.2 (main, Feb  6 2024, 20:19:44) [Clang 15.0.0 (clang-1500.1.0.2.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import shelve
>>> with shelve.open("myfile"):
...     pass
... 
>>> quit()

% ls
myfile.db

Furthermore, if I attempt to open an existing file as "myfile.db" (with the extension), I get the following error:

% python
Python 3.12.2 (main, Feb  6 2024, 20:19:44) [Clang 15.0.0 (clang-1500.1.0.2.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import shelve
>>> with shelve.open("myfile.db"):
...     pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/homebrew/Cellar/[email protected]/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/shelve.py", line 243, in open
    return DbfilenameShelf(filename, flag, protocol, writeback)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/shelve.py", line 227, in __init__
    Shelf.__init__(self, dbm.open(filename, flag), protocol, writeback)
                         ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.12.2_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/dbm/__init__.py", line 89, in open
    raise error[0]("db type could not be determined")
dbm.error: db type could not be determined

Opening the existing file as simply "myfile" with no extension works fine, however.

  1. How do I prevent shelve.open from appending ".db" to the filename?
  2. Why can't I open existing databases if I specify their ".db" extension?

Neither of these issues happen on Python 3.10.12 on Ubuntu 22, so I'm not sure if it's a Python version thing, or a platform thing.

Share Improve this question asked Mar 13 at 12:54 Jason CJason C 40.5k15 gold badges135 silver badges198 bronze badges 3
  • 1 "The filename specified is the base filename for the underlying database. As a side-effect, an extension may be added to the filename..." – jonrsharpe Commented Mar 13 at 13:22
  • 2 Furthermore, nothing is specified as a change for the actual name of the database between 3.10 and 3.12 But the underlying used database seems to depend on the OS and on the available interfaces (gdbm or ndbm). IMHO it is likely to be a platform thing. – Serge Ballesta Commented Mar 13 at 13:27
  • Is there a way to get the actual filename that will be used, given the base filename? – Jason C Commented Mar 13 at 13:42
Add a comment  | 

1 Answer 1

Reset to default 2

Why can't I open existing databases if I specify their ".db" extension?

After scrying shelve source code it could be unveiled that shelve.open("myfile") does result in calling dbm.open(filename, 'c') After scrying dbm source code it could be unveiled that this does depend on dbm.whichdb, where following line could be found

f = io.open(filename + b".db", "rb")

therefore if you attempt to do shelve.open("myfile.db") whichdb would be looking for myfile.db.db.

How do I prevent shelve module from appending ".db" to filename?

If you would do that this would most likely cause dbm.whichdb to malfunction for ndbm and dumbdm as it rely on extensions to detect nature of system used, as unveiled in comments

# Check for ndbm first -- this has a .pag and a .dir file
# Check for dumbdbm next -- this has a .dir and a .dat file

whilst for sqlite3 and gnu it should would work independently from extensions as detection rely on headers (see source code linked above for details).

发布评论

评论列表(0)

  1. 暂无评论