2017-02-22 14 views
5

pongongo/pandasでmongoDbを一括更新/挿入する方法を教えてください。 私が得るエラーはbatch op errors occurredです 私がしたい理由は、私がしたい"_id"を設定しているからです。最初の実行ではコードは正常に実行されますが、2回目には失敗します。私はワークフローでパンダを使いたい。データにはdatetimeオブジェクトがあります。MongoDBでPyMongoを一括挿入/更新する

upsert = Trueの構文は、Updateとはまったく異なります。 updateの効率的な解決策が役立ちます。"_id"または"qid"を設定できます。 しかし、python datetimeオブジェクトがあります!

InSQL = 'SELECT * from database2.table2 ' 
sqlOut = pd.read_sql(InSQL,cxn) 
sqlOut['_id'] = "20170101" + ":"+ sqlOut['Var'] 

dfOut = sqlOut.to_json(orient='records',date_format='iso') 
try: 
    db["test"].insert_many(json.loads(dfOut)) 
except Exception as e: print e 

私は無回答で、有効期限が切れ PTの恵みを、与えています。多分重複する_idによって引き起こさうーん...

+0

Mongoは 'string base input 'を使用し、変数の挿入を許可しません(オペレータのみ)[これをチェックしてください](http://stackoverflow.com/questions/2803852/python-date-string-to-date-object)、 'json.loads(dfOut)'あなたはエントリとしてローカル変数を挿入することはできません!主キー 'YYYYmmDDHHMMSS' +' Counter value' – dsgdfg

+0

'BulkWriteError'の詳細を掘り下げて、何が起こっているのかを知ることができます。あなたの個人的に定義されたIDが重複しているか、または12バイトの制限に違反している可能性があります。詳細については、http://stackoverflow.com/questions/30355790/mongodb-bulk-write-errorを参照してください。 –

+0

_idが初めて動作したことから、12バイトの制限は問題ではないことがわかります。はい、_idまたはgidはdupsであり、更新に必要です。 – Merlin

答えて

0

をupdate_many使用2回目以降の呼び出しで既存のドキュメントのフィールドと競合するフィールドを含むドキュメントを挿入しようとすると、エラーが発生します。正確には、あなたの設定_idが明示的に設定されている可能性があります。その場合、コレクションの既存の_id値と競合します。

MongoDB automatically creates an unique index on _id。重複する値を禁止します。

は、最初のバージョン(最初のバージョンのドキュメントを挿入したもの)の後にドキュメントを更新または交換してください。確かに、コレクション内の既存ではない文書を挿入したり、既存の文書を更新したりする「アップサート」の概念があります。

あなたのオプション:

  • 最も効率的な:それの効率もフィールドがついでにためのケースであるコレクション、にインデックス化されているかどうかに依存していることをpymongo.collection.Collection.bulk_write

    import pymongo 
    
    operations = [pymongo.operations.ReplaceOne(
        filter={"_id": doc["_id"]}, 
        replacement=doc, 
        upsert=True 
        ) for doc in json.loads(dfOut)] 
    
    result = db["test"].bulk_write(operations) 
    # handle results 
    

注意_id。 (もpymongo.operations.ReplaceOne参照)あなたのコレクションを

  • ループをして(非効率的ではないバルクので)

    import pymongo 
    
    results = [] 
    for doc in json.load(dfOut): 
        result = db["test"].replace_one(
         filter={"_id": doc["_id"]}, 
         replacement=doc, 
         upsert=True 
         ) 
        results.append(result) 
    
    # handle results 
    

pymongo.collection.Collection.update_oneまたはpymongo.collection.Collection.replace_oneを呼び出す注:あなたがないのでpymongo.collection.Collection.update_manyは、あなたのニーズに適していないようです指定されたフィルタのすべての一致で同じ値を設定しようとしています。

関連する問題