Docs 菜单
Docs 主页
/ / /
pymongo
/

通用唯一 ID (UUID)

在此页面上

  • Overview
  • MongoDB UUID 简史
  • 指定 UUID 表示形式
  • 支持的 UUID 表示形式
  • UNSPECIFIED
  • STANDARD
  • PYTHON_LEGACY
  • JAVA_LEGACY
  • CSHARP_LEGACY
  • 故障排除
  • ValueError: 无法使用 UuidRepresentation.UNSPECIFIED 编码原生 uuid.UUID
  • API 文档

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

提示

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

考虑具有以下规范文本表示形式的 UUID:

00112233-4455-6677-8899-aabbccddeeff

最初,MongoDB 将 UUID 表示为子类型3的 BSON Binary值。 由于子类型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连接string中包含 uuidRepresentation 参数。 PyMongo 将指定的 UUID 表示形式用于对此MongoClient实例执行的所有操作。

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

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

从以下标签页中进行选择,查看如何指定上述选项。 要详细了解可用的 UUID 表示形式,请参阅支持的 UUID 表示形式。

uuidRepresentation参数接受 UuidRepresentation 枚举中定义的值。以下代码示例指定 STANDARD 作为 UUID 表示形式:

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

uuidRepresentation参数接受以下值:

  • unspecified

  • standard

  • pythonLegacy

  • javaLegacy

  • csharpLegacy

以下代码示例指定standard作为 UUID 表示形式:

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 表示形式:

uuidRepresentation
UUID编码为
Binary子类型4解码为
Binary子类型3解码为
UNSPECIFIED (默认)
Raise ValueError
Binary 子类型4
Binary 子类型3
Binary 子类型4
UUID
Binary 子类型3
Binary 具有标准字节顺序的子类型3
Binary 子类型4
UUID
Binary 具有 Java 传统字节顺序的子类型3
Binary 子类型4
UUID
Binary 具有 C# 传统字节顺序的子类型3
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_LEGACY类型的UUID对象。 转换后,该值与 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 表示形式对应于 v 4.0之前的 PyMongo 版本使用的传统 UUID 表示形式。 使用PYTHON_LEGACY UUID 表示形式时,PyMongo 将原生UUID对象编码为Binary子类型3对象,并保留与UUID.bytes属性相同的字节顺序。

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

  • UUID 是由使用早于 v 4.0的 PyMongo 版本的应用程序插入的。

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

JAVA_LEGACY UUID 表示形式对应于 MongoDB Java 驱动程序使用的 UUID 的传统表示形式。 使用JAVA_LEGACY UUID 表示形式时,PyMongo 使用 Java 传统字节顺序将原生UUID对象编码为Binary子类型3对象。

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

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

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

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

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

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

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

出现此错误的原因是,当 UUID 表示形式为UNSPECIFIED时,尝试将原生UUID对象编码为Binary对象,如以下代码示例所示:

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 文档:

后退

日期和时间