对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
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集合。选择SynchronousAsynchronous标签页以查看相应的代码:

sample_restaurants.restaurants.insert_one({"name" : "Mongo's Burgers"})
await 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() 方法,以提高类型安全性。选择SynchronousAsynchronous标签页以查看相应的代码:

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

提示

类型检查工具

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

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

以下示例将文档列表插入到 restaurants集合中。选择SynchronousAsynchronous标签页以查看相应的代码:

document_list = [
{ "name" : "Mongo's Burgers" },
{ "name" : "Mongo's Pizza" }
]
sample_restaurants.restaurants.insert_many(document_list)
document_list = [
{ "name" : "Mongo's Burgers" },
{ "name" : "Mongo's Pizza" }
]
await 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 类实例的列表。这增加了插入操作的类型安全性。选择SynchronousAsynchronous标签页以查看相应的代码:

class Restaurant(TypedDict):
name: str
document_list = [
Restaurant(name="Mongo's Burgers"),
Restaurant(name="Mongo's Pizza")
]
sample_restaurants.restaurants.insert_many(document_list)
class Restaurant(TypedDict):
name: str
document_list = [
Restaurant(name="Mongo's Burgers"),
Restaurant(name="Mongo's Pizza")
]
await sample_restaurants.restaurants.insert_many(document_list)

提示

类型检查工具

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

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

属性
说明

bypass_document_validation

如果设立为True ,则允许写入选择退出文档级验证。默认为
False

session

ClientSession的实例。

comment

要附加到操作的注释。 有关更多信息,请参阅 MongoDB Server 手册中的插入命令字段指南。

insert_many()方法接受前面的可选参数以及可选的ordered属性:

属性
说明

ordered

如果设立为True ,则驾驶员按规定的顺序向服务器发送文档。如果发生错误,驾驶员和服务器会取消所有剩余的插入操作。默认为
True

以下代码使用 insert_many() 方法将三个新文档插入到集合中。由于第二个方法参数为 bypass_document_validation = True,因此此插入操作会绕过文档级验证。选择SynchronousAsynchronous标签页以查看相应的代码:

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)
document_list = [
{ "name" : "Mongo's Burgers" },
{ "name" : "Mongo's Pizza" },
{ "name" : "Mongo's Tacos" }
]
await 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 文档: