我正在使用Flask和MongoDB开发Web应用程序。我使用(Flask-)MongoKit定义一个模式来验证我的数据。
在我的数据库中,有一个名为“users”的集合(见下文),其中包含一个字段“email”。我尝试在MongoKit文档(http://namlook.github.com/mongokit/indexes.html)中指定的该字段上创建唯一索引。但是,当我通过MongoDB客户端shell检查集合索引时,根本没有索引“email”。
我在网上发现了类似的问题:“唯一索引不起作用”(https://github.com/namlook/mongokit/issues/98)
有人知道为什么它不起作用吗?
用户收藏:
@db.register
class User(Model):
__collection__ = 'users'
structure = {
'first_name': basestring,
'last_name': basestring,
'email': basestring,
'password': unicode,
'registration_date': datetime,
}
required_fields = ['first_name', 'last_name', 'email', 'password', 'registration_date']
default_values = {
'registration_date': datetime.utcnow,
}
# Create a unique index on the "email" field
indexes = [
{
'fields': 'email', # note: this may be an array
'unique': True, # only unique values are allowed
'ttl': 0, # create index immediately
},
]
db.users.getIndexes()输出:
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "youthmind.users",
"name" : "_id_"
},
]
请注意,我也尝试没有'ttl':0,并且我能够使用以下代码创建索引:
db.users.create_index('email', unique=True)
我认为这会直接使用pymongo Connection对象。
提前感谢您的帮助。
答案 0 :(得分:4)
你正在按照自己的方式去做。从版本0.7.1(可能是0.8版本)开始,MongoKit中的自动索引创建已被删除。 Here是一个问题。
背后的原因是它必须在集合上调用ensureIndex
。名称的“确保”部分使它看起来像检查然后创建索引(如果它不存在),但Mongo的开发人员说它可能仍然结束(重新)创建整个索引,这可能非常昂贵。开发人员还说它应该被视为一项管理任务,而不是开发任务。
解决方法是自己为您在升级/创建脚本中定义的列表中的每个索引调用create_index
。
答案 1 :(得分:3)
是的,您需要使用单独的脚本来重新创建带索引的数据库。如果需要,它将被调用,而不是每次服务器运行时。例如:
def recreatedb(uri, database_name):
connection = Connection(uri)
connection.drop_database(database_name)
#noinspection PyStatementEffect
connection[database_name]
connection.register(_DOCUMENTS)
for document_name, obj in connection._registered_documents.iteritems():
obj.generate_index(connection[database_name][obj._obj_class.__collection__])
防止使用没有索引的数据库:
def init_engine(uri, database_name):
global db
connection = Connection(uri)
if database_name not in connection.database_names():
recreatedb(uri, database_name)
connection.register(_DOCUMENTS)
db = connection[database_name]
答案 2 :(得分:0)
我使用Flask-Script,因此很容易将Marboni的答案作为命令添加到我的管理脚本中,该脚本易于运行。
@manager.command
def setup_indexes():
"""
create index for all the registered_documents
"""
for doc in application.db.registered_documents:
collection = application.db[doc.__collection__]
doc.generate_index(collection)
我将我的数据库作为app(application.db)的成员保存,用于各种管理员工作。现在每当我添加少量索引或更改任何内容时,我都会运行我的经理命令。
./manage.py setup_indexes
您可以在此处详细了解经理模块 http://flask-script.readthedocs.org/en/latest/