汎用一意 ID(UUID)
項目一覧
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
パラメータは次の値を受け入れます。
unspecified
standard
pythonLegacy
javaLegacy
csharpLegacy
次のコード例では、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
引数を指定することもできます。 このメソッドの詳細については、「 データベースとコレクション ガイドの「 読み取り操作および書込み操作の構成」を参照してください。
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
引数を指定することもできます。 このメソッドの詳細については、 データベースとコレクション ガイドの「読み取り操作および書込み操作の構成」を参照してください。
サポートされている UUID 表現
次の表は、PyMongo がサポートする UUID 表現の概要をまとめたものです。
UUID 表現 | UUID を にエンコードする | Binary サブタイプ4を復号化 | Binary サブタイプ3を復号化 |
---|---|---|---|
UNSPECIFIED (デフォルト) | 発生 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
オブジェクトに変換する方法を示しています。 To do so, the code performs the following steps:
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 表現を使用します。 これは、次の条件の 両方 が満たされている場合に当てはまります。
UUID は v 4.0より前のバージョンの PyMongo を使用するアプリケーションによって挿入されました。
UUID 表現を挿入したアプリケーションで
STANDARD
UUID が指定されませんでした。
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 ドライバー を使用するアプリケーションによって挿入されました。
アプリケーションでは
STANDARD
UUID 表現が指定されませんでした。
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# ドライバー を使用するアプリケーションによって挿入されました。
アプリケーションでは
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 ドキュメントを参照してください。