Overview
MongoDB ドライバーは、汎用一意の識別子(UUID)をエンコードする方法は歴史的に異なります。 このガイドでは、PyMongo の UuidRepresentation構成オプションを使用して、UUID を操作するときに言語間の互換性を維持する方法を学習できます。
Tip
MongoDB アプリケーションでは、ドキュメントの一意の識別子としてObjectId型を使用できます。 可能な場合は、UUID の代わりにObjectIdを使用することを検討してください。
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 を保存または取得するときは、注意が必要です。 1 つの MongoDB ドライバーによって保存されたこの型の UUID は、別のドライバーによって検索されると、異なる値を持つ可能性があります。
UUID 表現の指定
PyMongo アプリケーションで UUID を正しく処理できるようにするには、 UuidRepresentationオプションを使用します。 このオプションは、ドライバーが UUID オブジェクトを BSON にエンコードし、BSON からBinaryサブタイプ3と4値をデコードする方法を決定します。
UUID 表現オプションは、次の方法で設定できます。
MongoClientを構築するときにuuidRepresentationパラメータを渡します。 PyMongo は、このMongoClientインスタンスで実行されるすべての操作に対して指定された UUID 表現を使用します。MongoDB接続stringに
uuidRepresentationパラメータを含めます。 PyMongo は、このMongoClientインスタンスで実行されるすべての操作に対して指定された UUID 表現を使用します。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パラメータは次の値を受け入れます。
unspecifiedstandardpythonLegacyjavaLegacycsharpLegacy
次のコード例では、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)
Tip
database.with_options() メソッドを呼び出すときに codec_options 引数を指定することもできます。このメソッドの詳細については、「 データベースとコレクションガイド 」の「 CRUD操作の構成 」を参照してください。
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)
Tip
collection.with_options() メソッドを呼び出すときに codec_options 引数を指定することもできます。このメソッドの詳細については、データベースとコレクションガイドのCRUD操作の構成を参照してください。
サポートされている UUID 表現
次の表は、PyMongo がサポートする UUID 表現の概要をまとめたものです。
UUID 表現 | UUIDを にエンコードする | Binaryサブタイプ4を復号化 | Binaryサブタイプ3を復号化 |
|---|---|---|---|
| 発生 |
|
|
|
|
| |
|
|
| |
|
|
| |
|
|
|
次のセクションでは、前述の 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オブジェクトに変換する方法を示しています。 To do so, the code performs the following steps:
CSHARP_LEGACYUUID 表現を使用して、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 表現を使用します。 これは、次の条件の 両方 が満たされている場合に当てはまります。
UUID は v 4.0より前のバージョンの PyMongo を使用するアプリケーションによって挿入されました。
UUID 表現を挿入したアプリケーションで
STANDARDUUID が指定されませんでした。
JAVA_LEGACY
JAVA_LEGACY UUID 表現は、MongoDB Java ドライバーで使用される UUID のレガシー表現に対応します。 JAVA_LEGACY UUID 表現を使用する場合、PyMongo はネイティブUUIDオブジェクトを Java レガシー バイト順のBinaryサブタイプ3オブジェクトにエンコードします。
MongoDB から読み取っている UUID がJAVA_LEGACY表現を使用して挿入されている場合は、 JAVA_LEGACY UUID 表現を使用します。 これは、次の条件の 両方 が満たされている場合に当てはまります。
UUID は MongoDB Java ドライバー を使用するアプリケーションによって挿入されました。
アプリケーションでは
STANDARDUUID 表現が指定されませんでした。
CSHARP_LEGACY
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# ドライバー を使用するアプリケーションによって挿入されました。
アプリケーションでは
STANDARDUUID 表現が指定されませんでした。
トラブルシューティング
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 ドキュメントを参照してください。