通用唯一 ID (UUID)
在此页面上
Overview
MongoDB 驱动程序在编码通用唯一标识符(UUID) 的方式上一直存在差异。 在本指南中,您可以了解如何使用 PyMongo 的 UuidRepresentation
配置选项,在使用 UUID 时保持跨语言兼容性。
提示
在 MongoDB 应用程序中,您可以使用ObjectId
类型作为文档的唯一标识符。 尽可能考虑使用ObjectId
代替 UUID。
MongoDB 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 在由不同的驱动程序检索时可能具有不同的值。
指定 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
参数。 有关此方法的更多信息,请参阅《数据库和集合》指南中的配置读取和写入操作。
支持的 UUID 表示形式
下表总结了 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
注意
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
使用STANDARD
UUID 表示时,PyMongo 将原生UUID
对象编码为Binary
子类型4对象。 所有使用STANDARD
表示的 MongoDB 驱动程序都以相同的方式处理这些对象,字节顺序没有改变。
在所有新应用程序以及首次使用 MongoDB UUID 的所有应用程序中使用STANDARD
UUID 表示形式。
PYTHON_LEGACY
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
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
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 表示形式。
故障排除
ValueError: 无法使用 UuidRepresentation.UNSPECIFIED 编码原生 uuid.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})
API 文档
要了解有关 UUID 和 PyMongo 的更多信息,请参阅以下 API 文档: