Persists the model to the database. If the model holds no primary key,
        a new one will automatically created by RethinkDB. Otherwise it will
        overwrite the current model persisted to the database.

async def save(self):
        """
        Persists the model to the database. If the model holds no primary key,
        a new one will automatically created by RethinkDB. Otherwise it will
        overwrite the current model persisted to the database.
        """

        if hasattr(self, "before_save"):
            self.before_save()

        query = r.table(self.table_name)

        if self._state.get("id"):
            query = query \
                .get(self._state.get("id")) \
                .update(self.__db_repr, return_changes=True)
        else:
            query = query \
                .insert(self.__db_repr, return_changes=True)

        resp = await query.run(await conn.get())

        try:
            changes = resp["changes"]

            if len(changes) > 0:
                self.wrap(resp["changes"][0]["new_val"])
        except KeyError:
            raise UnexpectedDbResponse()

        if resp["skipped"] > 0:
            raise UnexpectedDbResponse(
                "Model with id `%s` not found in the database." %
                self._state.get("id"))

        return self