def safe_insert_voevent(session, etree):
    """
    Insert a VOEvent, or skip with a warning if it's a duplicate.

    NB XML contents are checked to confirm duplication - if there's a mismatch,
    we raise a ValueError.
    """
    new_row = Voevent.from_etree(etree)
    if not ivorn_present(session, new_row.ivorn):
        session.add(new_row)
    else:
        old_xml = session.query(Voevent.xml).filter(
            Voevent.ivorn == new_row.ivorn).scalar()
        if old_xml != new_row.xml:
            raise ValueError('Tried to load a VOEvent with duplicate IVORN,'
                             'but XML contents differ - not clear what to do.')
        else:
            logger.warning('Skipping insert for packet with duplicate IVORN, '
                        'XML matches OK.')