通过python mongoengine刷新mongodb集合结构

时间:2015-08-21 23:52:01

标签: python mongodb flask mongoengine

我正在编写一个简单的Flask应用程序,其唯一目的是学习Python和MongoDB。

我设法达到了定义所有集合的程度,并且CRUD操作一般都有效。现在,我真正想要理解的一件事是在更新其结构后如何刷新集合。例如,假设我有以下model

user.py

class User(db.Document, UserMixin):
    email            = db.StringField(required=True, unique=True)
    password         = db.StringField(required=True)
    active           = db.BooleanField()

    first_name       = db.StringField(max_length=64, required=True)
    last_name        = db.StringField(max_length=64, required=True)

    registered_at    = db.DateTimeField(default=datetime.datetime.utcnow())
    confirmed        = db.BooleanField()
    confirmed_at     = db.DateTimeField()

    last_login_at    = db.DateTimeField()
    current_login_at = db.DateTimeField()
    last_login_ip    = db.StringField(max_length=45)
    current_login_ip = db.StringField(max_length=45)
    login_count      = db.IntField()

    companies        = db.ListField(db.ReferenceField('Company'), default=[])
    roles            = db.ListField(db.ReferenceField(Role), default=[])

    meta = {
        'indexes': [
            {'fields': ['email'], 'unique': True}
        ]
    }

现在,我的user集合中已有条目,但我想将companies更改为:

company = db.ReferenceField('Company')

如何刷新集合的结构,而不必将整个数据库关闭?

我有一个manage.py脚本可以帮助我并提供一个shell:

#!/usr/bin/python

from flask.ext.script import Manager
from flask.ext.script.commands import Shell

from app import factory

app = factory.create_app()

manager = Manager(app)
manager.add_command("shell", Shell(use_ipython=True))

# manager.add_command('run_tests', RunTests())


if __name__ == "__main__":
    manager.run()

我尝试过几个命令,从我可以重新编译的信息和我的基本知识中获取信息:

>>> from app.models import db, User
>>> import mongoengine
>>> mongoengine.Document(User)
      field = iter(self._fields_ordered)
      AttributeError: 'Document' object has no attribute '_fields_ordered'
>>> mongoengine.Document(User).modify() # well, same result as above

有关如何实现这一目标的任何指示?

更新

我问这一切,因为我更新了我的user.py以匹配我的新请求,但是随时我与db交互,因为表的结构没有刷新,我得到了以下错误:

  

FieldDoesNotExist:字段'公司'在...上不存在   文档'用户',参考者:http://local.faqcolab.com/company

2 个答案:

答案 0 :(得分:0)

  

我更新了我的user.py以匹配我的新请求,但是每当我与db进行交互时,由于表的结构没有刷新,我收到以下错误

MongoDB没有像关系数据库那样的“表结构”。插入文档后,您无法通过更改文档模型来更改其架构。

我不想听起来我告诉你答案是使用不同的工具,但是看到像db.ListField(db.ReferenceField('Company'))这样的东西会让我觉得你的关系数据库会更好(Postgres Flask生态系统得到很好的支持。

Mongo最适合存储无模式文档(您不了解数据的结构,或者文档之间的差异很大)。除非您有这样的数据,否则值得查看其他选项。特别是因为你刚刚开始使用Python和Flask,所以没有必要让事情变得更难。

答案 1 :(得分:0)

解决方案比我预期的要容易:

db.getCollection('user').update(
    // query 
    {},

    // update 
    {
        $rename: {
            'companies': 'company'
        }
    },

    // options 
    {
        "multi" : true,  // update all documents
        "upsert" : false  // insert a new document, if no existing document match the query 
    }
);

每个{}

的说明
  • 首先是空的,因为我想更新user集合中的所有文档。
  • 第二个包含$rename,它是重命名我想要的字段的调用操作。
  • 最后包含要执行的查询的附加设置。