async def update(self, db=None, data=None):
        '''
        Update the entire document by replacing its content with new data, retaining its primary key
        '''
        db = db or self.db
        if data:  # update model explicitely with a new data structure
            # merge the current model's data with the new data
            self.import_data(data)
            # prepare data for database update
            data = self.prepare_data()
            # data = {x: ndata[x] for x in ndata if x in data or x == self.primary_key}
        else:
            data = self.export_data(native=True)

        if self.primary_key not in data or data[self.primary_key] is None:
            raise Exception('Missing object primary key')
        query = {self.primary_key: self.pk}
        for i in self.connection_retries():
            try:
                result = await db[self.get_collection_name()].find_one_and_replace(
                    filter=query,
                    replacement=data,
                    return_document=ReturnDocument.AFTER
                )
                if result:
                    updated_obj = self.create_model(result)
                    updated_obj._db = db
                    # emit post save
                    asyncio.ensure_future(post_save.send(
                        sender=self.__class__,
                        db=db,
                        instance=updated_obj,
                        created=False)
                    )
                    return updated_obj

                return None
            except ConnectionFailure as ex:
                exceed = await self.check_reconnect_tries_and_wait(i, 'update')
                if exceed:
                    raise ex
Update the entire document by replacing its content with new data, retaining its primary key