Execute raw sql
        :Parameters:

        - sql: string, sql to be executed

        :Return: the result of this execution

        If it's a select, return a list with each element be a DataRow instance

        Otherwise return raw result from the cursor (Should be insert or update or delete)

def raw(self, sql):
        """
        Execute raw sql
        :Parameters:

        - sql: string, sql to be executed

        :Return: the result of this execution

        If it's a select, return a list with each element be a DataRow instance

        Otherwise return raw result from the cursor (Should be insert or update or delete)

        """
        res = self.cursor.execute(sql)
        if self.cursor.description is None:
            return res

        rows = self.cursor.fetchall()
        columns = [d[0] for d in self.cursor.description]

        structured_rows = []
        for row in rows:
            data = {}
            for val, col in zip(row, columns):
                data[col] = val
            structured_rows.append(DataRow(data))

        return structured_rows