通过python mongoengine 刷新mongodb collection 结构
Refresh mongodb collection structure through python mongoengine
我正在编写一个简单的 Flask 应用程序,唯一目的是学习 Python 和 MongoDB。
我已经设法达到了定义所有 collection 的地步,并且 CRUD 操作通常可以正常工作。现在,我真正想了解的一件事是如何在更新其结构后刷新 collection。例如,假设我有以下 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
collection 中已有条目,但我想将 companies
更改为:
company = db.ReferenceField('Company')
如何刷新 collection 的结构,而不必关闭整个数据库?
我确实有一个 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
以匹配我的新请求,但是任何时候我与数据库本身交互,因为 table 的结构不是刷新后,出现以下错误:
FieldDoesNotExist: The field 'companies' does not exist on the
document 'User', referer: http://local.faqcolab.com/company
I have updated my user.py
to match my new requests, but anytime I interact with the db its self, since the table's structure was not refreshed, I get the following error
MongoDB 没有关系数据库那样的 "table structure"。插入文档后,您无法通过更改文档模型来更改其架构。
我不想听起来像是在告诉你答案是使用不同的工具,但是看到 db.ListField(db.ReferenceField('Company'))
这样的事情让我觉得你最好使用关系数据库(Postgres 在 Flask 生态系统中得到了很好的支持)。
Mongo 最适合存储无模式文档(您事先不知道数据的结构,或者文档之间的数据差异很大)。除非您有这样的数据,否则值得考虑其他选项。特别是因为您刚刚开始使用 Python 和 Flask,所以没有必要让事情变得比现在更难。
解决方案比我预期的要简单:
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
这是重命名我想要的字段的调用操作。
- 最后包含要执行的查询的附加设置。
我正在编写一个简单的 Flask 应用程序,唯一目的是学习 Python 和 MongoDB。
我已经设法达到了定义所有 collection 的地步,并且 CRUD 操作通常可以正常工作。现在,我真正想了解的一件事是如何在更新其结构后刷新 collection。例如,假设我有以下 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
collection 中已有条目,但我想将 companies
更改为:
company = db.ReferenceField('Company')
如何刷新 collection 的结构,而不必关闭整个数据库?
我确实有一个 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
以匹配我的新请求,但是任何时候我与数据库本身交互,因为 table 的结构不是刷新后,出现以下错误:
FieldDoesNotExist: The field 'companies' does not exist on the document 'User', referer: http://local.faqcolab.com/company
I have updated my
user.py
to match my new requests, but anytime I interact with the db its self, since the table's structure was not refreshed, I get the following error
MongoDB 没有关系数据库那样的 "table structure"。插入文档后,您无法通过更改文档模型来更改其架构。
我不想听起来像是在告诉你答案是使用不同的工具,但是看到 db.ListField(db.ReferenceField('Company'))
这样的事情让我觉得你最好使用关系数据库(Postgres 在 Flask 生态系统中得到了很好的支持)。
Mongo 最适合存储无模式文档(您事先不知道数据的结构,或者文档之间的数据差异很大)。除非您有这样的数据,否则值得考虑其他选项。特别是因为您刚刚开始使用 Python 和 Flask,所以没有必要让事情变得比现在更难。
解决方案比我预期的要简单:
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
这是重命名我想要的字段的调用操作。 - 最后包含要执行的查询的附加设置。