# 12.5. `dbm` - 与Unix“数据库”的接口

源代码： Lib/dbm/__init__.py

`dbm`是DBM数据库变体的通用接口 - `dbm.gnu`或`dbm.ndbm`。如果没有安装这些模块，将使用模块`dbm.dumb`中的慢但简单的实现。有一个第三方接口到Oracle Berkeley DB。

exception `dbm.``error`

  包含可由每个受支持的模块引发的异常的元组，具有唯一异常（也称为`dbm.error`）作为第一项 - 后者用于`dbm.error`

`dbm.``whichdb`(filename)

  此函数尝试猜测几个简单数据库模块中的哪一个可用 - `dbm.gnu`，`dbm.ndbm`或`dbm.dumb`以打开给定的文件。

  返回以下值之一：`None`如果文件无法读取或不存在则无法打开；如果文件的格式不能被猜测，则为空字符串（`''`）；或包含所需模块名称的字符串，例如`'dbm.ndbm'`或`'dbm.gnu'`。

`dbm.``open`(file, flag='r', mode=0o666)

  打开数据库文件文件并返回相应的对象。

  如果数据库文件已经存在，则`whichdb()`函数用于确定其类型，并使用适当的模块；如果不存在，则使用上面列出的可以导入的第一个模块。

  可选的flag参数可以是：

  值 | 含义
  --- | ---
  `'r'` | 打开现有数据库以进行只读（默认）
  `'w'` | 打开现有数据库进行读写
  `'c'` | 打开用于读取和写入的数据库，如果不存在则创建它
  `'n'` | 始终创建一个新的空数据库，打开进行读取和写入

  可选的mode参数是文件的Unix模式，仅在必须创建数据库时使用。它默认为八进制`0o666`（并且将由当前的umask修改）。

The object returned by `open()` supports the same basic functionality as dictionaries; keys and their corresponding values can be stored, retrieved, and deleted, and the `in` operator and the `keys()` method are available, as well as `get()` and `setdefault()`.

在版本3.2中更改： `get()`和`setdefault()`现在可在所有数据库模块中使用。

键和值始终以字节存储。这意味着，当使用字符串时，它们在被存储之前被隐式地转换为默认编码。

这些对象也支持在`with`语句中使用，在完成后会自动关闭它们。

在版本3.4中已更改：向由`open()`返回的对象添加了上下文管理协议的本机支持。

以下示例记录一些主机名和相应的标题，然后打印出数据库的内容：

    import dbm

    # Open database, creating it if necessary.
    with dbm.open('cache', 'c') as db:

        # Record some values
        db[b'hello'] = b'there'
        db['www.python.org'] = 'Python Website'
        db['www.cnn.com'] = 'Cable News Network'

        # Note that the keys are considered bytes now.
        assert db[b'www.python.org'] == b'Python Website'
        # Notice how the value is now in bytes.
        assert db['www.cnn.com'] == b'Cable News Network'

        # Often-used methods of the dict interface work too.
        print(db.get('python.org', b'not present'))

        # Storing a non-string key or value will raise an exception (most
        # likely a TypeError).
        db['www.yahoo.com'] = 4

    # db is automatically closed when leaving the with statement.

也可以看看

模块`shelve`
  持久性模块存储非字符串数据。

各个子模块将在以下部分中介绍。

## 12.5.1. `dbm.gnu` - GNU对dbm的重新解释

源代码： Lib/dbm/gnu.py

此模块与`dbm`模块非常相似，但使用GNU库`gdbm`来提供一些其他功能。请注意，由`dbm.gnu`和`dbm.ndbm`创建的文件格式不兼容。

`dbm.gnu`模块提供了一个到GNU DBM库的接口。`dbm.gnu.gdbm`对象的行为类似于映射（字典），除非键和值在存储之前始终转换为字节。打印`gdbm`对象不会打印键和值，并且不支持`items()`和`values()`方法。

exception `dbm.gnu.``error`

  在`dbm.gnu`上出现的特定错误，例如I / O错误。`KeyError`针对一般映射错误（例如指定不正确的键）引发。

`dbm.gnu.``open`(filename[, flag[, mode]])

  打开`gdbm`数据库并返回一个`gdbm`对象。filename参数是数据库文件的名称。

  可选的标志参数可以是：

  值 | 含义
  --- | ---
  `'r'` | 打开现有数据库以进行只读（默认）
  `'w'` | 打开现有数据库进行读写
  `'c'` | 打开用于读取和写入的数据库，如果不存在则创建它
  `'n'` | 始终创建一个新的空数据库，打开进行读取和写入

  可以将以下附加字符附加到标志以控制数据库的打开方式：

  值 | 含义
  --- | ---
  `'f'` | 以快速模式打开数据库。对数据库的写入将不同步。
  `'s'` | 同步模式。这将导致对数据库的更改立即写入文件。
  `'u'` | 不要锁定数据库。

  并非所有标志对`gdbm`的所有版本有效。模块常量`open_flags`是一个支持的标志字符串。如果指定了无效标志，则会引发异常`error`。

  可选的模式参数是文件的Unix模式，仅在必须创建数据库时使用。它默认为八进制`0o666`。

  除了类似字典的方法，`gdbm`对象有以下方法：

  `gdbm.``firstkey`()

    可以使用此方法和`nextkey()`方法循环数据库中的每个键。遍历按`gdbm`的内部散列值排序，并且不会按键值排序。此方法返回开始键。

  `gdbm.``nextkey`(key)

    返回遍历中键后面的键。以下代码打印数据库中的每个键`db`，而不必在包含它们的内存中创建一个列表：

        k = db.firstkey()
        while k != None:
            print(k)
            k = db.nextkey(k)

  `gdbm.``reorganize`()

    如果您执行了大量删除并希望缩小`gdbm`文件使用的空间，此例程将重组数据库。`gdbm`对象不会缩短数据库文件的长度，除非使用此重组；否则，删除的文件空间将被保留并作为新（键，值）对添加重新使用。

  `gdbm.``sync`()

    当数据库以快速模式打开时，此方法强制任何未写入的数据写入磁盘。

  `gdbm.``close`()

    关闭`gdbm`数据库。

## 12.5.2. `dbm.ndbm` - 基于ndbm的接口

源代码： Lib/dbm/ndbm.py

`dbm.ndbm`模块提供了一个到Unix“（n）dbm”库的接口。Dbm对象的行为像映射（字典），除了键和值总​​是存储为字节。打印`dbm`对象不会打印键和值，并且不支持`items()`和`values()`方法。

此模块可以与“经典”ndbm接口或GNU GDBM兼容性接口一起使用。在Unix上，configure脚本将尝试定位相应的头文件以简化构建此模块。

exception `dbm.ndbm.``error`

  在`dbm.ndbm`上引发的特定错误，例如I / O错误。`KeyError`针对一般映射错误（例如指定不正确的键）引发。

`dbm.ndbm.``library`

  使用的`ndbm`实施库的名称。

`dbm.ndbm.``open`(filename[, flag[, mode]])

  打开dbm数据库并返回`ndbm`对象。filename参数是数据库文件的名称（不含`.dir`或`.pag`扩展名）。

  可选的标志参数必须是以下值之一：

  值 | 含义
  --- | ---
  `'r'` | 打开现有数据库以进行只读（默认）
  `'w'` | 打开现有数据库进行读写
  `'c'` | 打开用于读取和写入的数据库，如果不存在则创建它
  `'n'` | 始终创建一个新的空数据库，打开进行读取和写入

  可选的模式参数是文件的Unix模式，仅在必须创建数据库时使用。它默认为八进制`0o666`（并且将由当前的umask修改）。

  除了类似字典的方法之外，`ndbm`对象还提供以下方法：

  `ndbm.``close`()

    关闭`ndbm`数据库。

## 12.5.3. `dbm.dumb` - 便携式DBM实施

源代码： Lib/dbm/dumb.py

注意

当更健壮的模块不可用时，`dbm.dumb`模块用作`dbm`模块的最后手段。`dbm.dumb`模块不是为了速度而编写的，并且不像其他数据库模块那么频繁。

`dbm.dumb`模块提供了一个持久的类字典接口，它完全用Python编写。与其他模块（例如`dbm.gnu`）不同，不需要外部库。与其他持久性映射一样，键和值始终以字节存储。

模块定义如下：

exception `dbm.dumb.``error`

  在`dbm.dumb`上出现的特定错误，例如I / O错误。`KeyError`针对一般映射错误（例如指定不正确的键）引发。

`dbm.dumb.``open`(filename[, flag[, mode]])

  打开`dumbdbm`数据库并返回dumbdbm对象。filename参数是数据库文件的基本名称（没有任何特定的扩展名）。当创建dumbdbm数据库时，将创建具有`.dat`和`.dir`扩展名的文件。

  可选的标志参数仅支持`'c'`和`'n'`值的语义。其他值将默认为始终为更新打开的数据库，如果不存在则将创建。

  可选的模式参数是文件的Unix模式，仅在必须创建数据库时使用。它默认为八进制`0o666`（并且将由当前的umask修改）。

  在版本3.5中更改： `open()`在标志值为`'n'`时始终创建一个新数据库。

  除了`collections.abc.MutableMapping`类提供的方法，`dumbdbm`对象提供以下方法：

  `dumbdbm.``sync`()

    同步磁盘目录和数据文件。此方法由`Shelve.sync()`方法调用。

  `dumbdbm.``close`()

    关闭`dumbdbm`数据库。