Overview
Históricamente, los controladores de MongoDB han diferido en la codificación de los identificadores únicos universales (UUID). En esta guía, aprenderá a usar los controladores de PyMongo. UuidRepresentation Opción de configuración para mantener la compatibilidad entre idiomas al trabajar con UUID.
Tip
En las aplicaciones MongoDB, se puede usar el tipo ObjectId como identificador único para un documento. Considere usar ObjectId en lugar de un UUID siempre que sea posible.
Una breve historia de los UUID de MongoDB
Considere un UUID con la siguiente representación textual canónica:
00112233-4455-6677-8899-aabbccddeeff
Originalmente, MongoDB representaba los UUID como valores BSON Binary del subtipo 3. Dado que el subtipo 3 no estandarizaba el orden de bytes de los UUID durante la codificación, los distintos controladores de MongoDB codificaban los UUID con distintos órdenes de bytes. Utilice las siguientes pestañas para comparar cómo los distintos controladores de lenguaje de MongoDB codificaban el UUID anterior al subtipo Binary 3:
00112233-4455-6677-8899-aabbccddeeff
33221100-5544-7766-8899-aabbccddeeff
77665544-3322-1100-ffee-ddccbbaa9988
Para estandarizar el orden de bytes del UUID, creamos el subtipo Binary 4. Si bien este subtipo se gestiona de forma consistente en todos los controladores de MongoDB, algunas implementaciones de MongoDB aún contienen valores UUID del subtipo 3.
Importante
Tenga cuidado al almacenar o recuperar UUID del subtipo 3. Un UUID de este tipo almacenado por un controlador de MongoDB podría tener un valor diferente al ser recuperado por otro controlador.
Especificar una representación UUID
Para garantizar que su aplicación PyMongo gestione los UUID correctamente, utilice la opción UuidRepresentation. Esta opción determina cómo el controlador codifica los objetos UUID a BSON y decodifica los valores de los subtipos Binary, 3 y 4 de BSON.
Puede configurar la opción de representación UUID de las siguientes maneras:
Pase el parámetro
uuidRepresentational construir unMongoClient. PyMongo utiliza la representación UUID especificada para todas las operaciones realizadas con esta instanciaMongoClient.Incluya el parámetro
uuidRepresentationen la cadena de conexión de MongoDB. PyMongo utiliza la representación UUID especificada para todas las operaciones realizadas con esta instanciaMongoClient.Pase el parámetro
codec_optionsal llamar al métodoget_database(). PyMongo utiliza la representación UUID especificada para todas las operaciones realizadas en la base de datos recuperada.Pase el parámetro
codec_optionsal llamar al métodoget_collection(). PyMongo utiliza la representación UUID especificada para todas las operaciones realizadas en la colección recuperada.
Seleccione una de las siguientes pestañas para ver cómo especificar las opciones anteriores. Para obtener más información sobre las representaciones UUID disponibles, consulte Representaciones UUID admitidas.
El uuidRepresentation parámetro acepta los valores definidos en la enumeración UuidRepresentation. El siguiente ejemplo de código especifica STANDARD para la representación UUID:
from bson.binary import UuidRepresentation client = pymongo.MongoClient("mongodb://<hostname>:<port>", uuidRepresentation=UuidRepresentation.STANDARD)
El parámetro uuidRepresentation acepta los siguientes valores:
unspecifiedstandardpythonLegacyjavaLegacycsharpLegacy
El siguiente ejemplo de código especifica standard para la representación UUID:
uri = "mongodb://<hostname>:<port>/?uuidRepresentation=standard" client = MongoClient(uri)
Para especificar el formato UUID al llamar al método get_database(), cree una instancia de la clase CodecOptions y pase el argumento uuid_representation al constructor. El siguiente ejemplo muestra cómo obtener una referencia a la base de datos usando el formato UUID CSHARP_LEGACY:
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)
Tip
También puede especificar el argumento codec_options al llamar al método database.with_options(). Para obtener más información sobre este método, consulte Configurar operaciones CRUD en la guía Bases de datos y colecciones.
Para especificar el formato UUID al llamar al método get_collection(), cree una instancia de la clase CodecOptions y pase el argumento uuid_representation al constructor. El siguiente ejemplo muestra cómo obtener una referencia de colección usando el formato UUID CSHARP_LEGACY:
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)
Tip
También puedes especificar el argumento codec_options cuando llames al método collection.with_options(). Para más información sobre este método, consulta Configurar operaciones CRUD en la guía de bases de datos y colecciones.
Representaciones UUID admitidas
La siguiente tabla resume las representaciones UUID que admite PyMongo:
Representación UUID | Codificar UUID a | Descodificar Binary subtipo 4 a | Descodificar Binary subtipo 3 a |
|---|---|---|---|
| Elevar |
|
|
|
|
| |
|
|
| |
|
|
| |
|
|
|
Las siguientes secciones describen las opciones previas de representación de UUID con más detalle.
UNSPECIFIED
Nota
UNSPECIFIED es la representación UUID predeterminada en PyMongo.
Al usar la representación UNSPECIFIED, PyMongo decodifica los valores BSON Binary en objetos Binary del mismo subtipo. Para convertir un objeto Binary en un objeto nativo UUID, llame al método Binary.as_uuid() y especifique un formato de representación UUID.
Si intenta codificar un objeto UUID con esta representación, PyMongo genera un ValueError. Para evitarlo, llame al método Binary.from_uuid() en el UUID, como se muestra en el siguiente ejemplo:
explicit_binary = Binary.from_uuid(uuid4(), UuidRepresentation.STANDARD)
El siguiente ejemplo de código muestra cómo recuperar un documento que contiene un UUID con la representación UNSPECIFIED y luego convertir el valor en un objeto UUID. Para ello, el código realiza los siguientes pasos:
Inserta un documento que contiene un campo
uuidusando la representación UUIDCSHARP_LEGACY.Recupera el mismo documento utilizando la representación
UNSPECIFIED. PyMongo decodifica el valor del campouuidcomo un objetoBinary.Llama al método
as_uuid()para convertir el valor del campouuiden un objetoUUIDde tipoCSHARP_LEGACY. Tras la conversión, este valor es idéntico al UUID original insertado por PyMongo.
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
Al usar la representación UUID STANDARD, PyMongo codifica los objetos nativos UUID en objetos Binary del subtipo 4. Todos los controladores de MongoDB que usan la representación STANDARD tratan estos objetos de la misma manera, sin cambios en el orden de bytes.
Utilice la representación UUID STANDARD en todas las aplicaciones nuevas y en todas las aplicaciones que trabajen con UUID de MongoDB por primera vez.
PYTHON_LEGACY
La representación UUID PYTHON_LEGACY corresponde a la representación tradicional de UUID utilizada por versiones de PyMongo anteriores a la v4.0. Al usar la representación UUID PYTHON_LEGACY, PyMongo codifica los objetos nativos UUID en objetos del subtipo Binary 3, conservando el mismo orden de bytes que la propiedad UUID.bytes.
Utilice la representación UUID PYTHON_LEGACY si el UUID que lee de MongoDB se insertó con la representación PYTHON_LEGACY. Esto será cierto si se cumplen los dos criterios siguientes:
El UUID fue insertado por una aplicación que utiliza una versión de PyMongo anterior a la v4.0.
La aplicación que insertó el UUID no especificó la representación UUID
STANDARD.
JAVA_LEGACY
La representación UUID JAVA_LEGACY corresponde a la representación tradicional de UUID utilizada por el controlador Java de MongoDB. Al usar la representación UUID JAVA_LEGACY, PyMongo codifica los objetos nativos UUID en objetos del subtipo Binary 3 con el orden de bytes tradicional de Java.
Utilice la representación UUID JAVA_LEGACY si el UUID que lee de MongoDB se insertó con la representación JAVA_LEGACY. Esto será cierto si se cumplen los dos criterios siguientes:
El UUID fue insertado por una aplicación que utiliza el controlador Java de MongoDB.
La aplicación no especificó la representación UUID
STANDARD.
CSHARP_LEGACY
La representación UUID CSHARP_LEGACY corresponde a la representación tradicional de UUID utilizada por el controlador MongoDB .NET/C#. Al usar la representación UUID CSHARP_LEGACY, PyMongo codifica los objetos nativos UUID en objetos del subtipo Binary 3 con el orden de bytes tradicional de C#.
Utilice la representación UUID CSHARP_LEGACY si el UUID que lee de MongoDB se insertó con la representación CSHARP_LEGACY. Esto será cierto si se cumplen los dos criterios siguientes:
El UUID fue insertado por una aplicación que utiliza el controlador MongoDB .NET/C#.
La aplicación no especificó la representación UUID
STANDARD.
Solución de problemas
ValueError: no se puede codificar uuid.UUID nativo con UuidRepresentation.UNSPECIFIED
Este error resulta de intentar codificar un objeto nativo UUID en un objeto Binary cuando la representación UUID es UNSPECIFIED, como se muestra en el siguiente ejemplo de código:
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.
En su lugar, debe convertir explícitamente un UUID nativo en un objeto Binary utilizando el método Binary.from_uuid(), como se muestra en el siguiente ejemplo:
explicit_binary = Binary.from_uuid(uuid4(), UuidRepresentation.STANDARD) unspec_collection.insert_one({'_id': 'bar', 'uuid': explicit_binary})
Documentación de la API
Para obtener más información sobre UUID y PyMongo, consulte la siguiente documentación de API: