文档菜单

文档首页开发应用程序Python 驱动程序PyMongo

通用唯一标识符 (UUIDs)

本页内容

  • 概述
  • MongoDB UUIDs 的简短历史
  • 指定 UUID 表示形式
  • 支持的 UUID 表示形式
  • 未指定
  • 标准
  • PYTHON_LEGACY
  • JAVA_LEGACY
  • CSHARP_LEGACY
  • 故障排除
  • ValueError: cannot encode native uuid.UUID with UuidRepresentation.UNSPECIFIED
  • API 文档

MongoDB 驱动程序在如何编码 通用唯一标识符 (UUIDs) 方面一直存在差异。在本指南中,您可以了解如何使用 PyMongo 的UuidRepresentation 配置选项,在处理 UUIDs 时保持跨语言兼容性。

提示

在 MongoDB 应用程序中,您可以使用 ObjectId 类型作为文档的唯一标识符。尽可能使用 ObjectId 代替 UUID。

考虑以下规范文本表示的 UUID

00112233-4455-6677-8899-aabbccddeeff

最初,MongoDB 将 UUIDs 表示为 BSON Binary 子类型的值 3。由于子类型 3 在编码期间没有标准化 UUIDs 的字节顺序,因此不同的 MongoDB 驱动程序以不同的字节顺序编码 UUIDs。使用以下选项卡比较不同的 MongoDB 语言驱动程序如何将前面的 UUID 编码为 Binary 子类型 3

为了标准化UUID字节顺序,我们创建了Binary子类型4。尽管这个子类型在MongoDB驱动程序中被一致处理,但某些MongoDB部署仍然包含子类型为3的UUID值。

重要

在存储或检索子类型3的UUID时请谨慎。由一个MongoDB驱动程序存储的UUID类型可能在由不同驱动程序检索时具有不同的值。

为了确保您的PyMongo应用程序正确处理UUID,请使用UuidRepresentation选项。此选项确定驱动程序如何将UUID对象编码为BSON以及如何从BSON解码Binary子类型3和4值。

您可以通过以下方式设置UUID表示方式

  • 在构造MongoClient时传递uuidRepresentation参数。PyMongo使用指定的UUID表示方式为此MongoClient实例的所有操作。

  • 在MongoDB连接字符串中包含uuidRepresentation参数。PyMongo使用指定的UUID表示方式为此MongoClient实例的所有操作。

  • 在调用get_database()方法时传递codec_options参数。PyMongo使用指定的UUID表示方式为检索到的数据库的所有操作。

  • 在调用get_collection()方法时传递codec_options参数。PyMongo使用指定的UUID表示方式为检索到的集合的所有操作。

选择以下选项卡以查看如何指定前面的选项。有关可用UUID表示方式的更多信息,请参阅支持的 UUID 表示形式.

以下表格总结了PyMongo支持的UUID表示方式

UUID表示方式
编码UUID
解码Binary子类型4到
解码Binary子类型3到
UNSPECIFIED(默认)
引发ValueError
Binary子类型4
Binary子类型3
Binary子类型4
UUID
Binary子类型3
Binary子类型3具有标准字节顺序
Binary子类型4
UUID
Binary子类型3具有Java遗留字节顺序
Binary子类型4
UUID
Binary子类型3具有C#遗留字节顺序
Binary子类型4
UUID

以下部分将更详细地描述前面的UUID表示方式选项。

注意

UNSPECIFIED是PyMongo中的默认UUID表示方式。

当使用 UNSPECIFIED 表示法时,PyMongo 将 BSON Binary 值解码为相同子类型的 Binary 对象。要将 Binary 对象转换为原生的 UUID 对象,请调用 Binary.as_uuid() 方法并指定 UUID 表示法格式。

如果您在尝试使用此表示法编码 UUID 对象时,PyMongo 将引发 ValueError。为了避免这种情况,请在 UUID 上调用 Binary.from_uuid() 方法,如下例所示

explicit_binary = Binary.from_uuid(uuid4(), UuidRepresentation.STANDARD)

以下代码示例展示了如何检索包含 UNSPECIFIED 表示法的 UUID 的文档,然后将该值转换为 UUID 对象。为此,代码执行以下步骤

  • 使用 CSHARP_LEGACY UUID 表示法插入包含 uuid 字段的文档。

  • 使用 UNSPECIFIED 表示法检索相同的文档。PyMongo 将 uuid 字段的值解码为 Binary 对象。

  • 调用 as_uuid() 方法将 uuid 字段的值转换为类型为 CSHARP_LEGACYUUID 对象。转换后,此值与 PyMongo 插入的原始 UUID 相同。

from bson.codec_options import CodecOptions, DEFAULT_CODEC_OPTIONS
from bson.binary import Binary, UuidRepresentation
from uuid import uuid4
# Using UuidRepresentation.CSHARP_LEGACY
csharp_opts = CodecOptions(uuid_representation=UuidRepresentation.CSHARP_LEGACY)
# Store a legacy C#-formatted UUID
input_uuid = uuid4()
collection = client.testdb.get_collection('test', codec_options=csharp_opts)
collection.insert_one({'_id': 'foo', 'uuid': input_uuid})
# Using UuidRepresentation.UNSPECIFIED
unspec_opts = CodecOptions(uuid_representation=UuidRepresentation.UNSPECIFIED)
unspec_collection = client.testdb.get_collection('test', codec_options=unspec_opts)
# UUID fields are decoded as Binary when UuidRepresentation.UNSPECIFIED is configured
document = unspec_collection.find_one({'_id': 'foo'})
decoded_field = document['uuid']
assert isinstance(decoded_field, Binary)
# Binary.as_uuid() can be used to convert the decoded value to a native UUID
decoded_uuid = decoded_field.as_uuid(UuidRepresentation.CSHARP_LEGACY)
assert decoded_uuid == input_uuid

当使用 STANDARD UUID 表示法时,PyMongo 将原生的 UUID 对象编码为 Binary 子类型 4 对象。所有使用 STANDARD 表示法的 MongoDB 驱动程序都以相同的方式处理这些对象,不更改字节序。

在所有新应用程序中以及所有首次使用 MongoDB UUID 的新应用程序中使用 STANDARD UUID 表示法。

PYTHON_LEGACY UUID 表示法对应于 PyMongo v4.0 之前版本使用的 UUID 的传统表示法。当使用 PYTHON_LEGACY UUID 表示法时,PyMongo 将原生 UUID 对象编码为 Binary 子类型 3 对象,保留与 UUID.bytes 属性相同的字节序。

如果从 MongoDB 读取的 UUID 是使用 PYTHON_LEGACY 表示法插入的,请使用 PYTHON_LEGACY UUID 表示法。如果满足以下两个条件,则此情况成立

  • UUID 是使用低于 v4.0 版本的 PyMongo 插入的。

  • 插入 UUID 的应用程序未指定 STANDARD UUID 表示法。

JAVA_LEGACY UUID 表示形式对应于 MongoDB Java 驱动程序使用的 UUID 的旧表示形式。当使用 JAVA_LEGACY UUID 表示形式时,PyMongo 将本地 UUID 对象编码为 Java 旧字节序的 Binary 子类型 3 对象。

如果您从 MongoDB 读取的 UUID 是使用 JAVA_LEGACY 表示形式插入的,请使用 JAVA_LEGACY UUID 表示形式。如果满足以下两个条件,则为真:

  • UUID 是使用 MongoDB Java 驱动程序插入的。

  • 应用程序没有指定 STANDARD UUID 表示形式。

CSHARP_LEGACY UUID 表示形式对应于 MongoDB .NET/C# 驱动程序使用的 UUID 的旧表示形式。当使用 CSHARP_LEGACY UUID 表示形式时,PyMongo 将本地 UUID 对象编码为 C# 旧字节序的 Binary 子类型 3 对象。

如果您从 MongoDB 读取的 UUID 是使用 CSHARP_LEGACY 表示形式插入的,请使用 CSHARP_LEGACY UUID 表示形式。如果满足以下两个条件,则为真:

  • UUID 是使用 MongoDB .NET/C# 驱动程序插入的。

  • 应用程序没有指定 STANDARD UUID 表示形式。

此错误是由于尝试将本地 UUID 对象编码为 Binary 对象,而 UUID 表示形式为 UNSPECIFIED,如下所示代码示例

unspecified_collection.insert_one({'_id': 'bar', 'uuid': uuid4()})
Traceback (most recent call last):
...
ValueError: cannot encode native uuid.UUID with UuidRepresentation.UNSPECIFIED.
UUIDs can be manually converted to bson.Binary instances using bson.Binary.from_uuid()
or a different UuidRepresentation can be configured. See the documentation for
UuidRepresentation for more information.

相反,您必须使用 Binary.from_uuid() 方法显式地将本地 UUID 转换为 Binary 对象,如下例所示

explicit_binary = Binary.from_uuid(uuid4(), UuidRepresentation.STANDARD)
unspec_collection.insert_one({'_id': 'bar', 'uuid': explicit_binary})

有关 UUID 和 PyMongo 的更多信息,请参阅以下 API 文档

← 日期和时间