def _save_create(self, doc, force_insert, write_concern): """Save a new document. Helper method, should only be used inside save(). """ doc_alias = None if doc.get('properties', {}).get('db_alias', None): doc_alias = doc['properties'].pop('db_alias') if doc_alias: alias_db = get_db(doc_alias) collection = alias_db.get_collection(self._meta['collection']) else: collection = self._get_collection() with set_write_concern(collection, write_concern) as wc_collection: if force_insert: return wc_collection.insert_one(doc).inserted_id # insert_one will provoke UniqueError alongside save does not # therefore, it need to catch and call replace_one. if "_id" in doc: raw_object = wc_collection.find_one_and_replace( {"_id": doc["_id"]}, doc) if raw_object: return doc["_id"] object_id = wc_collection.insert_one(doc).inserted_id return object_id
def _save_create(self, doc, force_insert, write_concern): """Save a new document. Helper method, should only be used inside save(). """ collection = self._get_collection() with set_write_concern(collection, write_concern) as wc_collection: if force_insert: return wc_collection.insert_one(doc).inserted_id # insert_one will provoke UniqueError alongside save does not # therefore, it need to catch and call replace_one. if '_id' in doc: raw_object = wc_collection.find_one_and_replace( {'_id': doc['_id']}, doc) if raw_object: return doc['_id'] object_id = wc_collection.insert_one(doc).inserted_id # In PyMongo 3.0, the save() call calls internally the _update() call # but they forget to return the _id value passed back, therefore getting it back here # Correct behaviour in 2.X and in 3.0.1+ versions if not object_id and pymongo.version_tuple == (3, 0): pk_as_mongo_obj = self._fields.get( self._meta['id_field']).to_mongo(self.pk) object_id = (self._qs.filter(pk=pk_as_mongo_obj).first() and self._qs.filter(pk=pk_as_mongo_obj).first().pk ) # TODO doesn't this make 2 queries? return object_id
def _save_update(self, doc, save_condition, write_concern): """Update an existing document. Helper method, should only be used inside save(). """ doc_alias = None if doc.get('properties', {}).get('db_alias', None): doc_alias = doc['properties'].pop('db_alias') if doc.get('properties', {}).get('conn_settings', {}): connection_properties = doc['properties'].pop('conn_settings') self.verify_connection_setting(doc_alias, connection_properties) if doc_alias: alias_db = get_db(doc_alias) collection = alias_db.get_collection(self._meta['collection']) else: collection = self._get_collection() object_id = doc["_id"] created = False select_dict = {} if save_condition is not None: select_dict = transform.query(self.__class__, **save_condition) select_dict["_id"] = object_id # Need to add shard key to query, or you get an error shard_key = self._meta.get("shard_key", tuple()) for k in shard_key: path = self._lookup_field(k.split(".")) actual_key = [p.db_field for p in path] val = doc for ak in actual_key: val = val[ak] select_dict[".".join(actual_key)] = val update_doc = self._get_update_doc() if update_doc: upsert = save_condition is None with set_write_concern(collection, write_concern) as wc_collection: last_error = wc_collection.update_one(select_dict, update_doc, upsert=upsert).raw_result if not upsert and last_error["n"] == 0: raise SaveConditionError( "Race condition preventing document update detected") if last_error is not None: updated_existing = last_error.get("updatedExisting") if updated_existing is False: created = True # !!! This is bad, means we accidentally created a new, # potentially corrupted document. See # https://github.com/MongoEngine/mongoengine/issues/564 return object_id, created
def _save_update(self, doc, save_condition, write_concern): """Update an existing document. Helper method, should only be used inside save(). """ collection = self._get_collection() object_id = doc['_id'] created = False select_dict = {} if save_condition is not None: select_dict = transform.query(self.__class__, **save_condition) select_dict['_id'] = object_id # Need to add shard key to query, or you get an error shard_key = self._meta.get('shard_key', tuple()) for k in shard_key: path = self._lookup_field(k.split('.')) actual_key = [p.db_field for p in path] val = doc for ak in actual_key: val = val[ak] select_dict['.'.join(actual_key)] = val update_doc = self._get_update_doc() if update_doc: upsert = save_condition is None with set_write_concern(collection, write_concern) as wc_collection: last_error = wc_collection.update_one( select_dict, update_doc, upsert=upsert ).raw_result if not upsert and last_error['n'] == 0: raise SaveConditionError('Race condition preventing' ' document update detected') if last_error is not None: updated_existing = last_error.get('updatedExisting') if updated_existing is False: created = True # !!! This is bad, means we accidentally created a new, # potentially corrupted document. See # https://github.com/MongoEngine/mongoengine/issues/564 return object_id, created
def test_set_write_concern(self): connect("mongoenginetest") class User(Document): name = StringField() collection = User._get_collection() original_write_concern = collection.write_concern with set_write_concern( collection, {"w": "majority", "j": True, "wtimeout": 1234} ) as updated_collection: assert updated_collection.write_concern.document == { "w": "majority", "j": True, "wtimeout": 1234, } assert original_write_concern.document == collection.write_concern.document
def _save_create(self, doc, force_insert, write_concern): """Save a new document. Helper method, should only be used inside save(). """ collection = self._get_collection() with set_write_concern(collection, write_concern) as wc_collection: if force_insert: return wc_collection.insert_one(doc).inserted_id # insert_one will provoke UniqueError alongside save does not # therefore, it need to catch and call replace_one. if '_id' in doc: raw_object = wc_collection.find_one_and_replace( {'_id': doc['_id']}, doc) if raw_object: return doc['_id'] object_id = wc_collection.insert_one(doc).inserted_id return object_id
def _save_update(self, doc, save_condition, write_concern): """Update an existing document. Helper method, should only be used inside save(). """ collection = self._get_collection() object_id = doc["_id"] created = False select_dict = {} if save_condition is not None: select_dict = transform.query(self.__class__, **save_condition) select_dict["_id"] = object_id select_dict = self._integrate_shard_key(doc, select_dict) update_doc = self._get_update_doc() if update_doc: upsert = save_condition is None with set_write_concern(collection, write_concern) as wc_collection: last_error = wc_collection.update_one( select_dict, update_doc, upsert=upsert, session=self._get_local_session(), ).raw_result if not upsert and last_error["n"] == 0: raise SaveConditionError( "Race condition preventing document update detected") if last_error is not None: updated_existing = last_error.get("updatedExisting") if updated_existing is False: created = True # !!! This is bad, means we accidentally created a new, # potentially corrupted document. See # https://github.com/MongoEngine/mongoengine/issues/564 return object_id, created
def _save_create(self, doc, force_insert, write_concern): """Save a new document. Helper method, should only be used inside save(). """ collection = self._get_collection() with set_write_concern(collection, write_concern) as wc_collection: if force_insert: return wc_collection.insert_one( doc, session=self._get_local_session()).inserted_id # insert_one will provoke UniqueError alongside save does not # therefore, it need to catch and call replace_one. if "_id" in doc: select_dict = {"_id": doc["_id"]} select_dict = self._integrate_shard_key(doc, select_dict) raw_object = wc_collection.find_one_and_replace( select_dict, doc, session=self._get_local_session()) if raw_object: return doc["_id"] object_id = wc_collection.insert_one( doc, session=self._get_local_session()).inserted_id return object_id