2012-10-10 100 views
3

我正在開發一個使用Flask和MongoDB的Web應用程序。我使用(Flask-)MongoKit來定義一個模式來驗證我的數據。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對象。

在此先感謝您的幫助。

回答

4

你正在這樣做,你應該怎麼做。從版本0.7.1(也許版本0.8)開始,自動創建索引已從MongoKit中刪除。 Here是它的問題。

它背後的原因是它必須在集合上調用ensureIndex。名稱中的「確保」部分看起來好像會檢查並在不存在的情況下創建索引,但Mongo的開發人員表示它可能仍然會結束(重新)創建整個索引,非常昂貴。開發者還表示,它應該被視爲一項管理任務,而不是一項開發任務。

解決的辦法是自己調用create_index,作爲升級/創建腳本中定義的列表中的每個索引。

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] 
+0

謝謝!這幫助了我。 – harry

0

我用瓶腳本所以很容易爲命令添加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/