文档菜单
文档首页
/ / /
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将UUID表示为BSON Binary 子类型3的值。因为子类型3在编码期间没有标准化UUID的字节序,所以不同的MongoDB驱动程序以不同的字节序编码UUID。使用以下选项卡比较不同MongoDB语言驱动程序将前面的UUID编码为Binary 子类型3的方式

00112233-4455-6677-8899-aabbccddeeff
33221100-5544-7766-8899-aabbccddeeff
77665544-3322-1100-ffee-ddccbbaa9988

为了标准化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表示形式.

uuidRepresentation 参数接受在以下枚举中定义的值:UuidRepresentation。以下代码示例指定了 UUID 表示法的 STANDARD

from bson.binary import UuidRepresentation
client = pymongo.MongoClient("mongodb://<hostname>:<port>",
uuidRepresentation=UuidRepresentation.STANDARD)

uuidRepresentation 参数接受以下值

  • 未指定

  • 标准

  • pythonLegacy

  • javaLegacy

  • csharpLegacy

以下代码示例指定 UUID 表示法的 standard

uri = "mongodb://<hostname>:<port>/?uuidRepresentation=standard"
client = MongoClient(uri)

当调用 get_database() 方法以指定 UUID 格式时,创建 CodecOptions 类的实例,并将 uuid_representation 参数传递给构造函数。以下示例显示了如何使用 CSHARP_LEGACY UUID 格式获取数据库引用

from bson.codec_options import CodecOptions
csharp_opts = CodecOptions(uuid_representation=UuidRepresentation.CSHARP_LEGACY)
csharp_database = client.get_database("database_name", codec_options=csharp_opts)

提示

您还可以在调用 database.with_options() 方法时指定 codec_options 参数。有关此方法的更多信息,请参阅配置读写操作指南中的数据库和集合。

当调用 get_collection() 方法以指定 UUID 格式时,创建 CodecOptions 类的实例,并将 uuid_representation 参数传递给构造函数。以下示例显示了如何使用 CSHARP_LEGACY UUID 格式获取集合引用

from bson.codec_options import CodecOptions
csharp_opts = CodecOptions(uuid_representation=UuidRepresentation.CSHARP_LEGACY)
csharp_collection = client.testdb.get_collection("collection_name", codec_options=csharp_opts)

提示

您还可以在调用 collection.with_options() 方法时指定 codec_options 参数。有关此方法的更多信息,请参阅配置读写操作指南中的数据库和集合。

以下表格总结了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 对象编码为子类型 4 的 Binary 对象。所有使用 STANDARD 表示法的 MongoDB 驱动程序以相同的方式处理这些对象,不更改字节顺序。

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

PYTHON_LEGACY UUID 表示法对应于 PyMongo 旧版本(小于 v4.0)中使用的 UUID 的旧表示法。当使用 PYTHON_LEGACY UUID 表示法时,PyMongo 将本机 UUID 对象编码为子类型 3 的 Binary 对象,保留与 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对象编码为二进制对象,而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转换为二进制对象,如下例所示

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

要了解更多关于UUID和PyMongo的信息,请参阅以下API文档

返回

日期和时间