4

我正在使用 Flask 和 MongoDB 开发一个 Web 应用程序。我使用 (Flask-)MongoKit 来定义一个模式来验证我的数据。

在我的数据库中,有一个名为“users”的集合(见下文),其中包含一个字段“email”。我尝试按照 MongoKit 文档 (http://namlook.github.com/mongokit/indexes.html) 中的规定在该字段上创建唯一索引。但是,当我通过 MongoDB 客户端 shell 检查集合索引时,根本没有索引“电子邮件”。

我在网上发现了一个类似的问题:“唯一索引不起作用”(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 对象。

在此先感谢您的帮助。

4

3 回答 3

4

你正在按照你应该做的方式去做。自 0.7.1 版(可能是 0.8 版?)起,自动索引创建已从 MongoKit 中删除。 是一个问题。

其背后的原因是它必须调用ensureIndex集合。名称的“确保”部分使它看起来像是会检查然后创建索引,如果它不存在,但来自 Mongo 的开发人员说它可能仍会结束(重新)创建整个索引,这可能非常昂贵。开发人员还表示,它应该被视为一项管理任务,而不是开发任务。

解决方法是为create_index您定义为升级/创建脚本的一部分的列表中的每个索引调用自己。

于 2012-10-11T00:40:02.940 回答
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]
于 2012-10-21T08:13:27.527 回答
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)

我将我的数据库作为各种管理内容的应用程序 (application.db) 的成员。现在,每当我添加一些索引或更改任何内容时,我都会运行我的管理器命令。

./manage.py setup_indexes

您可以在此处阅读有关管理器模块的更多信息 http://flask-script.readthedocs.org/en/latest/

于 2015-03-18T17:03:31.227 回答