无法使用pymong在mongodb中插入嵌套对象

2024-09-30 22:27:03 发布

您现在位置:Python中文网/ 问答频道 /正文

今天我来讨论一个使用python和mongodb对我来说毫无意义的问题。我是一个Go/C#开发人员,所以可能我遗漏了一些东西,但我有以下情况:

from datetime import datetime
from bson import ObjectId 

class DailyActivity:
    user_ids = []
    date = None

    def __init__(self, user_ids : [ObjectId] = [], date : datetime = None):
        self.user_ids = user_ids
        self.date = date


class ActivitiesThroughDays:
    daily_activies = []

    def add_daily_activity(self, daily_activity : DailyActivity = None):
        daily_activies.append(daily_activity)

然后我有了这两个类,还有另一个文件,其中包含一些使用mongodb的助手:

from pymongo import MongoClient

def get_client():
    return MongoClient('localhost', 27017)


def get_database(database_name: str = None):
    if database_name is None:
        raise AttributeError("database name is None.")
    return get_client().get_database(database_name)


def get_X_database():
    return get_database("X")

现在我们来讨论这个问题。。我现在正在构建一个简单的ActivitiesThroughDays对象,它只有一个DailyActivity包含X个用户id(作为ObjectId数组/列表)。你知道吗

但是,当我尝试插入一个时,我得到以下结果:

TypeError: document must be an instance of dict, bson.son.SON, bson.raw_bson.RawBSONDocument, or a type that inherits from collections.MutableMapping

这是引发异常的一段代码:

def insert_activities_though_days(activities_through_days: ActivitiesThroughDays = None):
    if activities_through_days is None:
        raise AttributeError("activities_through_days is None.")
    col = get_EM_column("activities_through_days")
    col.insert_one(activities_through_days)

基于上述问题,我尝试将ActivitiesThroughDays转换为dic/json:

col.insert_one(activities_through_days.__dict__)

bson.errors.InvalidDocument: cannot encode object: models. DailyActivity. DailyActivity object at 0x10eea0320, of type: class 'models. DailyActivity. DailyActivity'

col.insert_one(json.dumps(activities_through_days))

TypeError: Object of type ActivitiesThroughDays is not JSON serializable

基于此,我开始在谷歌上搜索不同的解决方案,找到了如下解决方案:

def to_dict(obj):
    if not hasattr(obj,"__dict__"):
        return obj
    result = {}
    for key, val in obj.__dict__.items():
        if key.startswith("_"):
            continue
        element = []
        if isinstance(val, list):
            for item in val:
                element.append(to_dict(item))
        else:
            element = to_dict(val)
        result[key] = element
    return result

但我得到了:

bson.errors.InvalidDocument: cannot encode object: property object at 0x10229aa98, of type: class 'property'


我前进的每一步都会出现另一个问题。。。对我来说,这一切都毫无意义,因为。。在某个地方应该有一个通用的序列化程序/反序列化程序,它将从1行转换要插入mongodb中的任何嵌套对象/数组。。你知道吗

另外,从我尝试的一个解决方案中,我发现ObjectId在映射到json/dict时被忽略了(我不记得是哪一个)

我根本不是一个Python开发人员所以请随时给我一些提示:)

谢谢


Tags: nonegetreturnifisdefdaysdatabase
1条回答
网友
1楼 · 发布于 2024-09-30 22:27:03

pymongo的接口需要dict,.__dict__是一个非常低级的属性。你知道吗

如果您尝试从头开始为mongodb构建ORM/ODM,恐怕会花费大量精力。你知道吗

在python中存在mongodb的ORM/ODM库(mongoenginepymodm非常相似),它们可以帮助您快速地完成工作。你知道吗

以下几行代码显示了使用mongoengine时模型的外观以及如何保存它们:

import datetime as dt
from mongoengine import *

connect(host='mongodb://localhost:27017/testdb')

class User(Document):
    email = EmailField(required=True)

class DailyActivity(Document):
    users = ListField(ReferenceField(User))
    date = DateTimeField(default=dt.datetime.utcnow)

user = User(email='test@garbage.com').save()
user2 = User(email='test2@garbage.com').save()

activity = DailyActivity(users=[user, user2]).save()

我希望这有帮助

相关问题 更多 >