ドキュメントの挿入
項目一覧
Overview
このガイドでは、PyMongo を使用して挿入操作を実行し、MongoDB コレクションにドキュメントを追加する方法を学習できます。
挿入操作は、1 つ以上のドキュメントを MongoDB コレクションに挿入します。 挿入操作は、 メソッドまたはinsert_one()
insert_many()
メソッドを使用して実行できます。
注意
_id フィールドは一意である必要があります
MongoDBコレクションでは、各ドキュメントに一意の値を持つ _id
フィールドが含まれている必要があります。
_id
フィールドに値を指定する場合は、その値がコレクション全体で一意であることを確認する必要があります。値を指定しない場合、ドライバーはフィールドに一意の ObjectId
値を自動的に生成します。
一意性を確保するために、ドライバーが _id
値を自動的に生成することをお勧めします。重複した _id
値はユニークインデックス制約に違反するため、ドライバーはエラーを返します。
サンプル データ
このガイドの例では、 Atlas サンプル データセットの
sample_restaurants.restaurants
コレクションを使用します。 MongoDB Atlas クラスターを無料で作成して、サンプル データセットをロードする方法については、 「 PyMongo を使い始める 」チュートリアルを参照してください。
1つのドキュメントの挿入
MongoDB コレクションに単一のドキュメントを追加するには、 insert_one()
メソッドを呼び出して、追加するドキュメントを渡します。
次の例では、 restaurants
コレクションにドキュメントを挿入します。
sample_restaurants.restaurants.insert_one({"name" : "Mongo's Burgers"})
カスタムクラスのインスタンスを insert_one()
メソッドに渡すこともできます。これにより、型チェックツールを使用している場合、追加の型の安全性が確保されます。渡すインスタンスは、TypedDict
クラスから継承する必要があります。
注意
Python 3.7 以前の TypedDiction
TypedDictionクラスは typing
モジュールにあります。このモジュールはPython 3.8 以降でのみ利用可能です。Pythonの以前のバージョンで TypedDict
クラスを使用するには、 mapping_extentionsパッケージをインストールします。
次の例では、型の安全性を高めるために、Restaurant
クラスのインスタンスを insert_one()
メソッドに渡します。
class Restaurant(TypedDict): name: str sample_restaurants.restaurants.insert_one(Restaurant(name="Mongo's Burgers")
複数のドキュメントの挿入
MongoDB コレクションに複数のドキュメントを追加するには、 insert_many()
メソッドを呼び出して、追加するドキュメントのリストを渡します。
次の例では、ドキュメントのリストをrestaurants
コレクションに挿入します。
document_list = [ { "name" : "Mongo's Burgers" }, { "name" : "Mongo's Pizza" } ] sample_restaurants.restaurants.insert_many(document_list)
カスタムクラスのインスタンスのリストを insert_many()
メソッドに渡すこともできます。これにより、型チェックツールを使用している場合、追加の型の安全性が確保されます。渡す インスタンスは、TypedDict
クラスから継承する必要があります。
注意
Python 3.7 以前の TypedDiction
TypedDictionクラスは typing
モジュールにあります。このモジュールはPython 3.8 以降でのみ利用可能です。Pythonの以前のバージョンで TypedDict
クラスを使用するには、 mapping_extentionsパッケージをインストールします。
次の例では、insert_many()
メソッドを呼び出し、Restaurant
クラスのインスタンスを含むリストを渡します。これにより、 挿入操作に型の安全性が追加されます。
class Restaurant(TypedDict): name: str document_list = [ Restaurant(name="Mongo's Burgers"), Restaurant(name="Mongo's Pizza") ] sample_restaurants.restaurants.insert_many(document_list)
挿入動作の変更
insert_one()
メソッドはオプションで、挿入操作を構成するために使用できるオプションを表す追加のパラメーターを受け入れます。 追加のパラメーターを指定しない場合、ドライバーは挿入をカスタマイズしません。
プロパティ | 説明 |
---|---|
| If set to True , allows the write to opt out of
document-level validation.Defaults to False . |
| An instance of ClientSession . |
| A comment to attach to the operation. For more information, see the insert command
fields guide in the
MongoDB Server manual for more information. |
insert_many()
メソッドは、前述の任意パラメータと任意のordered
プロパティを受け入れます。
プロパティ | 説明 |
---|---|
| If set to True , the driver sends documents to the
server in the order provided. If an error occurs, the driver
and server cancel all remaining insert operations.Defaults to True . |
例
次のコードでは、 insert_many()
メソッドを使用して 3 つの新しいドキュメントをコレクションに挿入します。 2 番目のメソッド引数はbypass_document_validation = True
であるため、この挿入操作はドキュメント レベルの検証をバイパスします。
document_list = [ { "name" : "Mongo's Burgers" }, { "name" : "Mongo's Pizza" }, { "name" : "Mongo's Tacos" } ] sample_restaurants.restaurants.insert_many(document_list, bypass_document_validation = True)
トラブルシューティング
クライアント タイプの注釈
MongoClient
オブジェクトに型注釈を追加しない場合、型チェッカーに次のようなエラーが表示される場合があります。
from pymongo import MongoClient client = MongoClient() # error: Need type annotation for "client"
解決策としては、MongoClient
オブジェクトを client: MongoClient
または client: MongoClient[Dict[str, Any]]
として注釈を付けることです。
互換性のないタイプ
型のヒントとして MongoClient
を指定しているが、ドキュメント、キー、値のデータ型を含めない場合、型チェッカーに次のようなエラーが表示される場合があります。
error: Dict entry 0 has incompatible type "str": "int"; expected "Mapping[str, Any]": "int"
解決策としては、次のタイプのヒントを MongoClient
オブジェクトに追加することです。
``client: MongoClient[Dict[str, Any]]``
insert_one()
メソッドにリストを渡すと、同様のエラーが表示される場合があります。
error: Argument 1 to "insert_one" of "Collection" has incompatible type "List[Dict[<nothing>, <nothing>]]"; expected "Mapping[str, Any]"
このエラーは、insert_one()
メソッドがリストではなくドキュメントを受け入れたために発生します。このエラーは、ドキュメントを insert_one()
メソッドに渡すか、代わりに insert_many()
メソッドを呼び出すことで解決できます。
TypedDiction がない _id キー
_id
フィールドを指定しない場合、 PyMongo はそれをドキュメントに自動的に挿入します。_id
フィールドの値は実行時に取得できますが、MyPy や別のツールを使用して静的型チェックを実行すると、クラス内の _id
フィールドは見つからず、次のようなエラーが表示されます。以下は次のとおりです。
TypedDict has no key "_id"
これは、次のようなコードによって発生します。
from typing import TypedDict from pymongo import MongoClient from pymongo.collection import Collection class Movie(TypedDict): name: str year: int client: MongoClient = MongoClient() collection: Collection[Movie] = client.test.test inserted = collection.insert_one(Movie(name="Jurassic Park", year=1993)) result = collection.find_one({"name": "Jurassic Park"}) # _id is present but was added by PyMongo; this will raise a type-checking error assert result["_id"]
解決策の 1 つは、_id
フィールドを使用する行の末尾に # type:ignore
コメントを追加することです。このコメントは、 行によって発生するエラーを無視するように型チェック ツールに指示します。次の例は、このソリューションを実装する方法を示しています。
from typing import TypedDict from pymongo import MongoClient from pymongo.collection import Collection class Movie(TypedDict): name: str year: int collection: Collection[Movie] = client.test.test inserted = collection.insert_one( Movie(name="Jurassic Park", year=1993) ) result = collection.find_one({"name": "Jurassic Park"}) assert result is not None assert result["_id"] # type:ignore[typeddict-item]
型エラーを無視する代わりに、 モデルクラスに _id
フィールドを含め、クラスインスタンスを作成するときにこのフィールドの値を明示的に指定することで、型エラーを回避できます。次のコードは、このソリューションを実装する方法を示しています。
from typing import TypedDict from pymongo import MongoClient from pymongo.collection import Collection from bson import ObjectId class Movie(TypedDict): _id: ObjectId name: str year: int collection: Collection[ExplicitMovie] = client.test.test inserted = collection.insert_one( ExplicitMovie(_id=ObjectId(), name="Jurassic Park", year=1993) ) result = collection.find_one({"name": "Jurassic Park"}) assert result is not None assert result["_id"]
カスタムクラスに _id
フィールドを追加する際の条件の 1 つは、作成するクラスのすべてのインスタンスのフィールドの値を含める必要があることです。これを回避するには、NotRequired
型のヒントを含む typing.NotRequired
パッケージをインストールします。この型ヒントを _id
フィールドに使用すると、コンパイル時に型エラーが発生することなく、実行時に _id
フィールドの値にアクセスできます。
次のコード例は、このソリューションを実装する方法を示しています。
from typing import TypedDict, NotRequired from pymongo import MongoClient from pymongo.collection import Collection from bson import ObjectId class Movie(TypedDict): _id: NotRequired[ObjectId] name: str year: int client: MongoClient = MongoClient() collection: Collection[Movie] = client.test.test inserted = collection.insert_one(Movie(name="Jurassic Park", year=1993)) result = collection.find_one({"name": "Jurassic Park"}) assert result is not None assert result["_id"]
重要
Python 3.11+ が必要ではありません
NoRequiredクラスはPython. 311以降でのみ利用可能です。Pythonの以前のバージョンで を使用するには、代わりに
NotRequired
mapping_extentionsパッケージをインストールします。
詳細情報
PyMongoを使用してドキュメントを挿入する実行可能なコード例については、CRUD操作を参照してください。
API ドキュメント
このガイドで説明したメソッドや型の詳細については、次の API ドキュメントを参照してください。