Overview
Históricamente, los controladores de MongoDB han diferido en la forma en que codifican los identificadores únicos universales (UUID). En esta guía, puedes aprender cómo usar la PyMongo UuidRepresentation Opción de configuración para mantener la compatibilidad entre idiomas al trabajar con UUID.
Tip
En las aplicaciones de MongoDB, puedes utilizar el tipo ObjectId como un identificador único para un documento. Considera usar ObjectId en lugar de un UUID donde 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 de subtipo 3. Debido a que el subtipo 3 no estandarizó el orden de los bytes de los UUID durante la codificación, diferentes drivers de MongoDB codificaron los UUID con diferentes órdenes de bytes. Utilice las siguientes pestañas para comparar las formas en que diferentes controladores de idiomas de MongoDB codificaron el UUID anterior en el subtipo Binary de 3:
00112233-4455-6677-8899-aabbccddeeff
33221100-5544-7766-8899-aabbccddeeff
77665544-3322-1100-ffee-ddccbbaa9988
Para estandarizar el orden de bytes UUID, creamos el subtipo Binary 4. Aunque este subtipo se maneja de manera coherente en todos los drivers de MongoDB, algunas implementaciones de MongoDB aún contienen valores UUID del subtipo 3.
Importante
Tenga cuidado al almacenar o recuperar UUIDs del subtipo 3. Un UUID de este tipo almacenado por un controlador de MongoDB puede tener un valor diferente cuando se recupera por un controlador diferente.
Especificar una representación de 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 de UUID especificada para todas las operaciones realizadas con esta instanciaMongoClient.Pasa 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 parámetro uuidRepresentation acepta los valores definidos en la enum 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 utilizando 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 Configura 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 de UUID que PyMongo admite:
Representación UUID | Codificar UUID a | Descodificar Binary subtipo 4 a | Descodificar Binary subtipo 3 a |
|---|---|---|---|
| Levantar |
|
|
|
|
| |
|
|
| |
|
|
| |
|
|
|
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 utilizar la representación UNSPECIFIED, PyMongo decodifica los valores BSON Binary a objetos Binary del mismo subtipo. Para convertir un objeto Binary en un objeto nativo UUID, se debe llamar al método Binary.as_uuid() y especificar un formato de representación UUID.
Si intentas codificar un objeto UUID mientras usas esta representación, PyMongo genera un ValueError. Para evitar esto, llama 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 a un objeto UUID. Para hacerlo, 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. Después de la conversión, este valor es idéntico al UUID original introducido 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
Cuando se utiliza la representación UUID STANDARD, PyMongo codifica los objetos UUID nativos en objetos de subtipo Binary 4. Todos los controladores de MongoDB que utilicen 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 aquellas aplicaciones que trabajen con UUIDs 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.
Utiliza la representación UUID PYTHON_LEGACY si el UUID que estás leyendo desde MongoDB se insertó utilizando la representación PYTHON_LEGACY. Esto será cierto si se cumplen ambos de los siguientes criterios:
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 de JAVA_LEGACY corresponde a la representación heredada de UUIDs utilizada por el controlador Java de MongoDB. Al usar la representación UUID JAVA_LEGACY, PyMongo codifica objetos nativos UUID en objetos de subtipo Binary 3 con el orden de bytes heredado de Java.
Utiliza la representación UUID JAVA_LEGACY si el UUID que estás leyendo desde MongoDB se insertó utilizando la representación JAVA_LEGACY. Esto será cierto si se cumplen ambos de los siguientes criterios:
El UUID fue insertado por una aplicación que utiliza el controlador Java de MongoDB.
La aplicación no especificó la representación UUID de
STANDARD.
CSHARP_LEGACY
La representación UUID CSHARP_LEGACY corresponde a la representación heredada de UUIDs utilizada por el driver .NET/C# de MongoDB. Al usar la representación UUID CSHARP_LEGACY, PyMongo codifica los objetos nativos UUID en objetos de subtipo Binary 3 con el orden de bytes heredado de C#.
Utiliza la representación UUID CSHARP_LEGACY si el UUID que estás leyendo desde MongoDB se insertó utilizando la representación CSHARP_LEGACY. Esto será cierto si se cumplen ambos de los siguientes criterios:
El UUID fue insertado por una aplicación que utiliza el controlador MongoDB .NET/C#.
La aplicación no especificó la representación UUID de
STANDARD.
Solución de problemas
ValueError: no se puede codificar uuid.UUID nativo con UuidRepresentation.UNSPECIFIED
Este error se produce al intentar codificar un objeto nativo UUID a 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 cambio, debes convertir explícitamente un UUID nativo en un objeto Binary usando 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: