<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:

async def save(self, db=None):
        '''
        If object has _id, then object will be created or fully rewritten.
        If not, object will be inserted and _id will be assigned.
        '''
        self._db = db or self.db
        data = self.prepare_data()
        # validate object
        self.validate()
        # connect to DB to save the model
        for i in self.connection_retries():
            try:
                created = False if '_id' in data else True
                result = await self.db[self.get_collection_name()].insert_one(data)
                self._id = result.inserted_id
                # emit post save
                asyncio.ensure_future(post_save.send(
                    sender=self.__class__,
                    db=self.db,
                    instance=self,
                    created=created)
                )
                break
            except ConnectionFailure as ex:
                exceed = await self.check_reconnect_tries_and_wait(i, 'save')
                if exceed:
                    raise ex