与 MongoDB 结合使用时,Dataclass 中的 '_id' 应该如何处理?
How should I deal with '_id' in Dataclass when used in combination with MongoDB?
我有一个 MongoDB 并且想将每个文档存储为 python 数据 class 的一个实例。我对“_id”有疑问。当我创建本地实例时,我不想分配“_id”。但是,在检索文档时,实例应包含“_id”。
我的方法是将“_id”设置为 None。当我将实例插入数据库时,这不起作用。值 None
作为“_id”传递。
有没有一种方法可以使用数据class 创建一个模型,这样我就可以将本地数据和检索到的数据存储为相同 class 的实例?
from dataclasses import dataclass
from typing import List
from bson import ObjectId
@dataclass
class Article:
name: str
quantity: int
_id: ObjectId = None
description: str = ""
插入本地实例
import dataclasses
from pymongo import MongoClient
article = Article(name="pen", description="A writing device", quantity=100)
self.client = MongoClient()
self.db = self.client.warehouse
self.collection = self.db["articles"]
res = self.collection.insert_one(dataclasses.asdict(article)) # <-- Should not contain "_id"
检索文档
res = self.collection.find_one("_id": ObjectID())
article = Article(**res) # <-- Article should contain id
from dataclasses import dataclass, asdict
from typing import Optional
@dataclass
class Article:
name: str
quantity: int
id: Optional[int] = None
description: str = ''
def to_short_dict(self):
result = asdict(self)
result.pop('id')
return result
# not contain "id"
input_data = {
'name': 'pen', 'quantity': 100, 'description': 'A writing device',
}
article = Article(**input_data)
assert article.to_short_dict() == input_data
# contain "id"
input_data = {
'id': 1,
'name': 'pen', 'quantity': 100, 'description': 'A writing device',
}
article = Article(**input_data)
assert asdict(article) == input_data
我试图想出一个更通用的解决方案:
我创建了一个接口 MongoDataclass
,我的所有模型都继承自该接口。该接口包含一个方法,该方法 returns 所有值不是 None
的键值对作为字典。
我认为这是有道理的,因为 MongoDB 是无模式的,我不想在我的文档中存储任何 None
值。这也解决了“_id”的问题。
import abc
from dataclasses import dataclass
@dataclass
class MongoDataclass(abc.ABC):
def as_json_wo_none(self):
return {key: value for key, value in dataclasses.asdict(self).items() if value is not None}
我有一个 MongoDB 并且想将每个文档存储为 python 数据 class 的一个实例。我对“_id”有疑问。当我创建本地实例时,我不想分配“_id”。但是,在检索文档时,实例应包含“_id”。
我的方法是将“_id”设置为 None。当我将实例插入数据库时,这不起作用。值 None
作为“_id”传递。
有没有一种方法可以使用数据class 创建一个模型,这样我就可以将本地数据和检索到的数据存储为相同 class 的实例?
from dataclasses import dataclass
from typing import List
from bson import ObjectId
@dataclass
class Article:
name: str
quantity: int
_id: ObjectId = None
description: str = ""
插入本地实例
import dataclasses
from pymongo import MongoClient
article = Article(name="pen", description="A writing device", quantity=100)
self.client = MongoClient()
self.db = self.client.warehouse
self.collection = self.db["articles"]
res = self.collection.insert_one(dataclasses.asdict(article)) # <-- Should not contain "_id"
检索文档
res = self.collection.find_one("_id": ObjectID())
article = Article(**res) # <-- Article should contain id
from dataclasses import dataclass, asdict
from typing import Optional
@dataclass
class Article:
name: str
quantity: int
id: Optional[int] = None
description: str = ''
def to_short_dict(self):
result = asdict(self)
result.pop('id')
return result
# not contain "id"
input_data = {
'name': 'pen', 'quantity': 100, 'description': 'A writing device',
}
article = Article(**input_data)
assert article.to_short_dict() == input_data
# contain "id"
input_data = {
'id': 1,
'name': 'pen', 'quantity': 100, 'description': 'A writing device',
}
article = Article(**input_data)
assert asdict(article) == input_data
我试图想出一个更通用的解决方案:
我创建了一个接口 MongoDataclass
,我的所有模型都继承自该接口。该接口包含一个方法,该方法 returns 所有值不是 None
的键值对作为字典。
我认为这是有道理的,因为 MongoDB 是无模式的,我不想在我的文档中存储任何 None
值。这也解决了“_id”的问题。
import abc
from dataclasses import dataclass
@dataclass
class MongoDataclass(abc.ABC):
def as_json_wo_none(self):
return {key: value for key, value in dataclasses.asdict(self).items() if value is not None}