MongoDB - MongoEngine - 保存嵌入的文档不起作用 - 没有属性保存

时间:2012-08-06 09:02:25

标签: mongodb pymongo mongoengine database

我有一个嵌入式文档类Post和一个父类Thread

class Thread(Document):
    ...
    posts = ListField(EmbeddedDocumentField("Post"))

class Post(EmbeddedDocument): 
    attribute = StringField()
    ...

我想创建一个新帖子并将其添加到ListField课程中的Thread

我的代码如下所示:

post = Post()
post.attribute = "noodle"
post.save()
thread.posts.append(post)
thread.save()

但是我收到以下错误消息:

  

“'发布'对象没有属性'保存'”

如果我跳过post.save(),则Post附加一个空的Thread对象。

有什么想法吗?

2 个答案:

答案 0 :(得分:6)

嵌入式文档不是作为单独的,与文档实例分开的实例存在的,即保存嵌入的文档,您必须将文档本身保存在嵌入的文档中;另一种看待它的方法是,如果没有实际的文档,就无法存储嵌入的文档。

这也是因为,虽然您可以过滤包含特定嵌入文档的文档,但您不会收到匹配的嵌入文档本身 - 您将收到它所属的整个文档。

thread = Thread.objects.first()  # Get the thread
post = Post()
post.attribute = "noodle"
thread.posts.append(post)  # Append the post
thread.save()  # The post is now stored as a part of the thread

答案 1 :(得分:4)

您的代码看起来很好 - 您确定没有其他线程对象吗?下面是一个测试用例证明你的代码(没有post.save()步骤)。你安装了什么版本?

import unittest
from mongoengine import *


class Test(unittest.TestCase):

    def setUp(self):
        conn = connect(db='mongoenginetest')

    def test_something(self):

        class Thread(Document):
            posts = ListField(EmbeddedDocumentField("Post"))

        class Post(EmbeddedDocument):
            attribute = StringField()

        Thread.drop_collection()

        thread = Thread()
        post = Post()
        post.attribute = "Hello"

        thread.posts.append(post)
        thread.save()

        thread = Thread.objects.first()
        self.assertEqual(1, len(thread.posts))
        self.assertEqual("Hello", thread.posts[0].attribute)