2014-09-16 7 views
5

sono in grado di fare qualsiasi scrittura ad un database MongoDB remoto. Sono in grado di connettersi e fare ricerche (ad esempio, trovare). Mi collego in questo modo:errore durante la scrittura pymongo

conn = pymongo.MongoClient(db_uri,slaveOK=True) 
db = conn.test_database 
coll = db.test_collection 

Ma quando provo ad inserire,

coll.insert({'a':1}) 

mi imbatto in un errore:

--------------------------------------------------------------------------- 
AutoReconnect        Traceback (most recent call last) 
<ipython-input-56-d4ffb9e3fa79> in <module>() 
----> 1 coll.insert({'a':1}) 

/usr/lib/python2.7/dist-packages/pymongo/collection.pyc in insert(self, doc_or_docs, manipulate, safe, check_keys, continue_on_error, **kwargs) 
    410    message._do_batched_insert(self.__full_name, gen(), check_keys, 
    411          safe, options, continue_on_error, 
--> 412          self.uuid_subtype, client) 
    413 
    414   if return_one: 

/usr/lib/python2.7/dist-packages/pymongo/mongo_client.pyc in _send_message(self, message, with_last_error, command, check_primary) 
    1126    except (ConnectionFailure, socket.error), e: 
    1127     self.disconnect() 
-> 1128     raise AutoReconnect(str(e)) 
    1129    except: 
    1130     sock_info.close() 

AutoReconnect: not master 

Se rimuovo il slaveOK=True (impostazione al suo valore predefinito valore false) poi ho ancora possibile connettersi, ma la legge (e scrive) non riuscire:

AutoReconnect        Traceback (most recent call last) 
<ipython-input-70-6671eea24f80> in <module>() 
----> 1 coll.find_one() 

/usr/lib/python2.7/dist-packages/pymongo/collection.pyc in find_one(self, spec_or_id, *args, **kwargs) 
    719       *args, **kwargs).max_time_ms(max_time_ms) 
    720 
--> 721   for result in cursor.limit(-1): 
    722    return result 
    723   return None 

/usr/lib/python2.7/dist-packages/pymongo/cursor.pyc in next(self) 
    1036    raise StopIteration 
    1037   db = self.__collection.database 
-> 1038   if len(self.__data) or self._refresh(): 
    1039    if self.__manipulate: 
    1040     return db._fix_outgoing(self.__data.popleft(), 

/usr/lib/python2.7/dist-packages/pymongo/cursor.pyc in _refresh(self) 
    980        self.__skip, ntoreturn, 
    981        self.__query_spec(), self.__fields, 
--> 982        self.__uuid_subtype)) 
    983    if not self.__id: 
    984     self.__killed = True 

/usr/lib/python2.7/dist-packages/pymongo/cursor.pyc in __send_message(self, message) 
    923             self.__tz_aware, 
    924             self.__uuid_subtype, 
--> 925             self.__compile_re) 
    926   except CursorNotFound: 
    927    self.__killed = True 

/usr/lib/python2.7/dist-packages/pymongo/helpers.pyc in _unpack_response(response, cursor_id, as_class, tz_aware, uuid_subtype, compile_re) 
    99   error_object = bson.BSON(response[20:]).decode() 
    100   if error_object["$err"].startswith("not master"): 
--> 101    raise AutoReconnect(error_object["$err"]) 
    102   elif error_object.get("code") == 50: 
    103    raise ExecutionTimeout(error_object.get("$err"), 

AutoReconnect: not master and slaveOk=false 
.515.053.691,36321 milioni

Sto collegando in modo errato? C'è un modo per specificare la connessione alla replica primaria?

+0

Sembra che si connette a un nodo secondario/slave. I nodi secondari e slave sono nodi di sola lettura che si replicano dal primario. – rmcc

+1

E possono essere letti solo quando 'slaveOK = True' – wdberkeley

+0

Come connettersi al nodo primario? C'è un modo per far sì che pymongo lo gestisca, cioè connettersi al secondario, ma riconnettersi al primario se si tenta di scrivere? – amd

risposta

11

AutoReconnect: not master significa che l'operazione non riesce, perché il nodo su cui si sta tentando di eseguire il comando non è il primario di un set di repliche, in cui il comando (per esempio, un'operazione di scrittura) richiede che il nodo di essere un primario. L'impostazione di slaveOK=True consente di leggere solo da un nodo secondario, dove per impostazione predefinita è possibile leggere solo dal primario.

MongoClient è automaticamente in grado di rilevare e connettersi al primario se il nome del set di repliche viene fornito al costruttore con replicaSet=<replica set name>. Vedere "Connecting to a Replica Set" nello PyMongo docs.

A parte, slaveOK è obsoleto, sostituito da ReadPreference. È possibile specificare un ReadPreference durante la creazione del client o durante l'emissione di query, se si desidera targetizzare un nodo diverso da quello primario.