def _maybe_init_tags(self, run_id, tag_to_metadata):
    """Returns a tag-to-ID map for the given tags, creating rows if needed.

    Args:
      run_id: the ID of the run to which these tags belong.
      tag_to_metadata: map of tag name to SummaryMetadata for the tag.
    """
    cursor = self._db.cursor()
    # TODO: for huge numbers of tags (e.g. 1000+), this is slower than just
    # querying for the known tag names explicitly; find a better tradeoff.
    cursor.execute('SELECT tag_name, tag_id FROM Tags WHERE run_id = ?',
                   (run_id,))
    tag_to_id = {row[0]: row[1] for row in cursor.fetchall()
                 if row[0] in tag_to_metadata}
    new_tag_data = []
    for tag, metadata in six.iteritems(tag_to_metadata):
      if tag not in tag_to_id:
        tag_id = self._create_id()
        tag_to_id[tag] = tag_id
        new_tag_data.append((run_id, tag_id, tag, time.time(),
                             metadata.display_name,
                             metadata.plugin_data.plugin_name,
                             self._make_blob(metadata.plugin_data.content)))
    cursor.executemany(
        """
        INSERT INTO Tags (
          run_id, tag_id, tag_name, inserted_time, display_name, plugin_name,
          plugin_data
        ) VALUES (?, ?, ?, ?, ?, ?, ?)
        """,
        new_tag_data)
    return tag_to_id