0

我正在尝试在 mongodb 上执行更新,使用 motor 和 tornadoweb 以及以下代码:

@gen.coroutine
def set_project_status(self, pid, status):
    try:
        project = yield motor.Op(self.db[S.DB_PROJECT_TABLE].find_one, {'PID': pid})
        logging.debug('set_project_status old_id {0}'.format(project['_id']))

        project_update = yield motor.Op(self.db[S.DB_PROJECT_TABLE].update,
                           {'_id': ObjectId(project['_id'])}, {'STATUS': status})

        logging.debug('set_project_status saving')
        save = yield motor.Op(self.db[S.DB_PROJECT_TABLE].save, project_update)
        logging.debug('set_project_status saved {0}'.format(save))

        logging.debug('set_project_status saved id {0}'.format(project_update))

        project = yield motor.Op(self.db[S.DB_PROJECT_TABLE].find_one, {'PID': pid})
        logging.debug('set_project_status project {0}'.format(project))

        raise gen.Return(True)

    except Exception,e:
        logging.debug('{0} {1} {2}'.format(pid, status, e))
        raise gen.Return(False)

我在日志中得到的是:

set_project_status old_id 52d532d4b12c6478ce767a83
set_project_status saving
set_project_status saved 52d532d4b12c6478ce767a84
set_project_status saved id {u'ok': 1.0, u'err': None, u'connectionId': 2052, u'n': 1, u'updatedExisting': True, '_id': ObjectId('52d532d4b12c6478ce767a84')}
set_project_status project None

我得到了一些中间对象(u'updatedExisting ?),稍后没有。

我似乎,就像我应该做一些'提交'左右。有任何想法吗?

问候!

4

1 回答 1

2

只需这样做:

@gen.coroutine
def set_project_status(self, pid, status):
    try:
        result = yield motor.Op(self.db[S.DB_PROJECT_TABLE].update,
                       {'PID': pid}, {'$set': {'STATUS': status}})

        logging.debug('update result: {0}'.format(result))        
        project = yield motor.Op(self.db[S.DB_PROJECT_TABLE].find_one, {'PID': pid})
        logging.debug('set_project_status project {0}'.format(project))
    except Exception,e:
        logging.debug('{0} {1} {2}'.format(pid, status, e))
        raise gen.Return(False)

请参阅“更新”的文档

首先,您想使用 $set 更新文档中的单个字段。您的更新代码仅用 {'STATUS': status} 替换整个文档,删除任何其他字段。我展示的代码只是设置了“状态”字段,而文档的其余部分保持不变。此外,如果 project['_id'] 已经是 ObjectId,则对其调用 ObjectId() 无效;这是不必要的。

您无需查找文档,然后更新它,然后保存它。只需发出“更新”。该文档会立即在 MongoDB 中更新。

'update' 的返回值不是更新的文档。返回值是一些关于操作的信息,例如'updatedExisting'和'n'。

在我展示的代码中,你找到了更新后的文档,所以你可以看到更新的效果。但这也是不必要的;一旦你有这个工作,你应该删除对 find_one 的调用。我只是检查一下result.get('n') == 1,然后返回 True。

(最后,只是检查一下:您在“PID”上有一个唯一索引,对吗?)

于 2014-01-14T14:43:15.687 回答