def ExecuteRemaining(self):
    """Executes the remaining queries that have been added.

    Raises:
      exceptions.BatchSqlManagerException: db_connection has been closed.
      psycopg2.Error/Warning
    """
    if not self.db_connection:
      raise exceptions.BatchSqlManagerException(
          ERR_BATCH_SQL_MANAGER_CLOSED)

    self.logger.debug("ExecuteRemaining...")
    self._InternalExecute()
    # Release the cursor instance
    if self.cursor:
      self.cursor.close()
      self.cursor = None
    self.logger.debug("ExecuteRemaining done.")
  def AddModify(self, command, parameters=None):
    """Adds a Sql modify statement to the batcher.

    After every "batch_count" statements, the current batch will be executed.

    Args:
      command: sql modify command string.
      parameters: parameters that will be bound to variables in the SQL
      statement string.

    Raises:
      exceptions.BatchSqlManagerException: db_connection has been closed.
      psycopg2.Error/Warning
    """
    if not self.db_connection:
      raise exceptions.BatchSqlManagerException(
          ERR_BATCH_SQL_MANAGER_CLOSED)

    try:
      # Create the cursor object if necessary.
      if not self.cursor:
        self.cursor = self.db_connection.Cursor()
        self.count = 0

      self.logger.debug("AddModify...")
      self.logger.debug(self.cursor.mogrify(command, parameters))
      self.cursor.execute(command, parameters)
      self.logger.debug("ok")
      self.count += 1
      if self.count >= self.batch_count:
        self._InternalExecute()

    except (psycopg2.Warning, psycopg2.Error) as e:
      logging.debug(
          "Error while executing Sql command: %s, params: %s\n"
          "Error: %s", command, parameters, e)
      self.db_connection.Rollback()
      self.cursor.close()
      self.cursor = None
      raise
  def Close(self):
    """Executes the batch query and release the references to the cursor object.

    This should be called at the very end of adding all queries to the
    BatchSqlManager (to make sure any remaining queries are executed.

    Raises:
      psycopg2.Error/Warning
    """
    if not self.db_connection:
      if self.count != 0:
        raise exceptions.BatchSqlManagerException(
            "Server-side Internal Error"
            " - db connection has been closed,"
            " while not all Sql statements are committed.")
      return  # already closed.

    self.logger.debug("Close...")
    self.ExecuteRemaining()
    self.logger.debug("Close done.")
    self.db_connection = None
    self.logger = None
  def AddModifySet(self, command, parameters):
    """Adds set of SQL modify statements to the batcher.

    It creates and executes set of SQL statements based on specified command
    and list of sequence of parameters.
    e.g.
    command = "INSERT INTO db_files_table (db_id, file_id) VALUES(%s, %s)"
    parameters = [(5, 100), (5, 101), (5, 102)]
    result statements:
    INSERT INTO db_files_table (db_id, file_id) VALUES(5, 100)
    INSERT INTO db_files_table (db_id, file_id) VALUES(5, 101)
    INSERT INTO db_files_table (db_id, file_id) VALUES(5, 102)

    After every "batch_count" SQL modify commands, the current batch will be
    executed.

    Args:
      command: sql modify command.
      parameters: list of sequence of parameters. Every sequence of parameters
      will be bound to variables in SQL statement string.

    Raises:
      exceptions.BatchSqlManagerException: db_connection has been closed.
      psycopg2.Error/Warning
    """
    if not self.db_connection:
      raise exceptions.BatchSqlManagerException(
          ERR_BATCH_SQL_MANAGER_CLOSED)

    assert parameters
    try:
      # Create the cursor object if necessary.
      if not self.cursor:
        self.cursor = self.db_connection.Cursor()
        self.count = 0

      self.logger.debug("AddModifySet...")
      self.logger.debug("parameters list length: %d", len(parameters))

      i = 0
      parameters_len = len(parameters)
      while i < parameters_len:
        num_elements_todo = parameters_len - i
        rest_count = self.batch_count - self.count
        if num_elements_todo >= rest_count:
          self.logger.debug("executemany(): command: %s, parameters: %s",
                            command,
                            ", ".join(map(str, parameters[i:i + rest_count])))
          self.cursor.executemany(command, parameters[i:i + rest_count])
          i += rest_count
          self._InternalExecute()
        else:
          self.logger.debug("executemany(): command: %s, parameters: %s",
                            command,
                            ", ".join(map(str, parameters[i:])))
          self.cursor.executemany(command, parameters[i:])
          self.count += num_elements_todo
          break
    except (psycopg2.Warning, psycopg2.Error) as e:
      logging.debug("Error while executing set of Sql commands.\n"
                    "Error: %s", e)
      self.db_connection.Rollback()
      self.cursor.close()
      self.cursor = None
      raise