Docs 菜单

插入文档

在本指南中,您可以了解如何使用 PyMongo 通过执行插入操作将文档添加到 MongoDB 集合。

插入操作将一个或多个文档插入 MongoDB 集合。 您可以使用 insert_one()insert_many()方法执行插入操作。

注意

_id字段必须是唯一的

在MongoDB集合中,每个文档都必须包含具有唯一值的 _id字段。

如果为 _id字段指定值,则必须确保该值在集合中是唯一的。如果不指定值,驾驶员会自动为该字段生成唯一的 ObjectId 值。

我们建议让驾驶员自动生成 _id 值以确保唯一性。重复的 _id 值违反了唯一索引约束,导致驾驶员返回错误。

本指南中的示例使用 Atlas示例数据集中sample_restaurants.restaurants集合。 要学习;了解如何创建免费的MongoDB Atlas 群集并加载示例数据集,请参阅 PyMongo入门教程。

要将单个文档添加到 MongoDB 集合,请调用insert_one()方法并传递要添加的文档。

以下示例将文档插入restaurants集合:

sample_restaurants.restaurants.insert_one({"name" : "Mongo's Burgers"})

您还可以将自定义类的实例传递给 insert_one() 方法。如果您使用类型检查工具,这将提供额外的类型安全性。您传递的实例必须从 TypedDict 类继承。

注意

Python 3.7 及更早版本中的 TypedDict

TypedDict 类位于 typing 模块中,该模块仅在Python 3.8 及更高版本中可用。要在早期版本的Python中使用 TypedDict 类,请安装typing_extensions包。

以下示例将 Restaurant 类的实例传递给 insert_one() 方法,以提高类型安全性:

class Restaurant(TypedDict):
name: str
sample_restaurants.restaurants.insert_one(Restaurant(name="Mongo's Burgers")

提示

类型检查工具

要学习;了解有关Python可用的类型检查工具的更多信息,请参阅“工具”页面上的“类型检查器”。

要将多个文档添加到 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 及更早版本中的 TypedDict

TypedDict 类位于 typing 模块中,该模块仅在Python 3.8 及更高版本中可用。要在早期版本的Python中使用 TypedDict 类,请安装typing_extensions包。

以下示例调用 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)

提示

类型检查工具

要学习;了解有关Python可用的类型检查工具的更多信息,请参阅“工具”页面上的“类型检查器”。

insert_one()方法可以选择接受其他参数,这些参数表示可用于配置插入操作的选项。 如果不指定任何其他参数,驱动程序将不会自定义插入操作。

属性
说明

bypass_document_validation

If set to True, allows the write to opt out of document-level validation.
Defaults to False.

session

An instance of ClientSession.

comment

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属性:

属性
说明

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()方法将三个新文档插入到集合中。 由于第二个方法参数为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: MongoClientclient: 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() 方法来解决此错误。

如果不指定 _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"]

一种解决方案是在使用 _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字段添加到自定义类的一个缺点是,您必须为所创建的类的每个实例包含该字段的值。为避免这种情况,您可以安装 typing.NotRequired包,其中包含 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"]

重要

NotRequired 需要Python 3.11+

NotRequired 类仅在Python 3.11 及更高版本中可用。要在早期版本的Python中使用 NotRequired,请安装typing_extensions包。

有关使用PyMongo插入文档的可运行代码示例,请参阅增删改查操作。

要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: