【问题标题】:'Collection' object is not callable. If you meant to call the 'save' method on a 'Collection' object it is failing because no such method exists'Collection' 对象不可调用。如果您打算在“集合”对象上调用“保存”方法,它会失败,因为不存在这样的方法
【发布时间】:2022-01-14 20:15:43
【问题描述】:

我正在使用 tornado 用 mongoDB 构建一个简单的网站。我使用python 3.7和最新版本的pymongo来控制MongoDB中的数据,但是当我使用save方法在MongoDB中编辑数据时,出现以下错误:

TypeError: 'Collection' 对象不可调用。如果您打算在 'Collection' 对象上调用 'save' 方法,它会失败,因为不存在这样的方法。

    def post(self, isbn=None):
        import time
        book_fields = ['isbn', 'title', 'subtitle', 'image', 'author', 'date_released', 'description']
        burtbook = self.application.db.BurtBook
        book = dict()
        if isbn:
            book = burtbook.find_one({"isbn":isbn})
        for key in book_fields:
            book[key] = self.get_argument(key, None)

        if isbn:
            burtbook.save(book)
        else:
            book['add_released'] = int(time.time())
            burtbook.insert_one(book)
        self.redirect("/recommended/")

请帮我修复这个错误。

【问题讨论】:

  • 我实际上也有同样的经历。你在使用烧瓶-pymongo 吗?我实际上找到了解决方法。我会发布我的答案

标签: python mongodb tornado


【解决方案1】:

嗯,我不知道为什么,但我认为自 2020 年底以来save 或其deprecated 存在错误?

救星方法将是:update_one($old_document, $keys_to_update)

我在 this reference 上看到您可以在原地更新 document 并保持 ObjectID 不变(您将拥有原始文档 ID)

你的代码会变成(cmets 会解释一切)

def post(self, isbn=None):
    import time
    book_fields = ['isbn', 'title', 'subtitle', 'image', 'author', 'date_released', 'description']
    burtbook = self.application.db.BurtBook
    book = dict()
    if isbn:
        book = burtbook.find_one({"isbn": isbn})
        # set is a specifier to mongo to update the values;
        # you just need to pass which value to modify on which key
        # example
        # keys_to_update = {"$set": { "bookName": "newNameSetByYou"}}
        # but the bookName key name remains the same
        keys_to_update = {"$set": {}}

    for key in book_fields:
        value = self.get_argument(key, None)
        book[key] = value
        if isbn:
            # here if isbn we create that dictionary to tell
            # mongo which value to modify on which key
            keys_to_update["$set"].update({
                key: value
            })
            # simple and old pythonic dict update

    if isbn:
        # here we update the document book with new values
        # from the above generated dict
        burtbook.update_one(book, keys_to_update)
        # just like the save()
        # save is deprecated boys, cant use it anymore ...
    else:
        book['add_released'] = int(time.time())
        burtbook.insert_one(book)
    self.redirect("/recommended/")

好吧,我为自己辩护,它无法测试你的代码,但我已经在我的项目中测试了相同的技术,它知道它对我有用。

告诉我它是否有效。节奏

编辑

另一个有用的reference

你也可以试试这个代码(在这里你用你想要的任何东西替换整个文档):

todos_collection = get_collection(todos_collection_name)
requested_todo = todos_collection.find_one({
    "_id": ObjectId(oid)
})

todos_collection.replace_one(requested_todo, {"something": "else"})
# this will replace the entire document `request_todo` with `{"something": "else"}`
# but it will keep the original `ObjectID`
# and thats is very useful

【讨论】:

  • 我刚刚将这个修改后的代码用于:if isbn: burtbook.update_one({"isbn":isbn},{"$set":book}) else: book['add_released'] = int(time.time()) burtbook.insert_one(book),它确实有效。感谢您的评论。
  • 等一下:使用这行burtbook.update_one({"isbn":isbn},{"$set":book}),您实际上用新的book 更新了旧的book,或者您只是在带有{"isbn":isbn} 的文档中添加一个新的book
  • 我更新了旧书,因为key isbn是这本书的旧key,所以它只是更新了DB中书的状态
猜你喜欢
  • 2020-01-21
  • 2017-06-23
  • 2021-08-06
  • 1970-01-01
  • 1970-01-01
  • 2021-04-22
  • 1970-01-01
  • 2016-12-03
  • 1970-01-01
相关资源
最近更新 更多