code: async def executemany(self, query, args):
          
          if not args:
              return
  
          if self._echo:
              logger.info("CALL %s", query)
              logger.info("%r", args)
  
          m = RE_INSERT_VALUES.match(query)
          if m:
              q_prefix = m.group(1)
              q_values = m.group(2).rstrip()
              q_postfix = m.group(3) or ''
              assert q_values[0] == '(' and q_values[-1] == ')'
              return (await self._do_execute_many(
                  q_prefix, q_values, q_postfix, args, self.max_stmt_length,
                  self._get_db().encoding))
          else:
              rows = 0
              for arg in args:
                  await self.execute(query, arg)
                  rows += self._rowcount
              self._rowcount = rows
          return self._rowcount
docs: Execute the given operation multiple times
  
          The executemany() method will execute the operation iterating
          over the list of parameters in seq_params.
  
          Example: Inserting 3 new employees and their phone number
  
              data = [
                  ('Jane','555-001'),
                  ('Joe', '555-001'),
                  ('John', '555-003')
                  ]
              stmt = "INSERT INTO employees (name, phone) VALUES ('%s','%s')"
              await cursor.executemany(stmt, data)
  
          INSERT or REPLACE statements are optimized by batching the data,
          that is using the MySQL multiple rows syntax.
  
          :param query: `str`, sql statement
          :param args: ``tuple`` or ``list`` of arguments for sql query