2014-09-16 2 views
5

Я не могу выполнить запись в удаленную базу данных mongodb. Я могу подключать и выполнять поиск (например, найти). Подключаю так:ошибка pymongo при записи

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

Но когда я пытаюсь вставить,

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

Я бегу в ошибку:

--------------------------------------------------------------------------- 
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 

Если я удалить slaveOK=True (установив ее на него по умолчанию значение False), то я все еще могу подключиться, но считывает (и пишет) сбой:

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 

Я неправильно подключаюсь? Есть ли способ указать соединение с основной репликой?

+0

Кажется, что вы подключаетесь к второстепенному/подчиненному узлу. Вторичные и подчиненные узлы являются узлами только для чтения, которые реплицируются из первичного. – rmcc

+1

И они могут быть прочитаны только после того, как 'slaveOK = True' – wdberkeley

+0

Как подключиться к основному узлу? Есть ли способ заставить pymongo справиться с этим, т. Е. Подключиться к вторичному, но повторно подключиться к первичному, если попытка записи будет предпринята? – amd

ответ

11

AutoReconnect: not master означает, что ваша операция не работает, поскольку узел, на котором вы пытаетесь выполнить команду, не является основным набором реплик, где команда (например, операция записи) требует, чтобы этот узел был основным. Установка slaveOK=True позволяет вам читать только со вторичного узла, где по умолчанию вы сможете читать только из основного.

MongoClient автоматически может обнаружить и подключиться к первичному, если имя набора реплик предоставлено конструктору с помощью replicaSet=<replica set name>. См. «Connecting to a Replica Set» в PyMongo docs.

Отклонено, slaveOK устарело, заменено на ReadPreference. Вы можете указать ReadPreference при создании клиента или при выпуске запросов, если вы хотите настроить таргетинг на узел, отличный от основного.