@transactional_session
def add_bad_pfns(pfns, account, state, reason=None, expires_at=None, session=None):
    '\n    Add bad PFNs.\n\n    :param pfns: the list of new files.\n    :param account: The account who declared the bad replicas.\n    :param state: One of the possible states : BAD, SUSPICIOUS, TEMPORARY_UNAVAILABLE.\n    :param reason: A string describing the reason of the loss.\n    :param expires_at: Specify a timeout for the TEMPORARY_UNAVAILABLE replicas. None for BAD files.\n    :param session: The database session in use.\n\n    :returns: True is successful.\n    '
    if isinstance(state, string_types):
        rep_state = BadPFNStatus[state]
    else:
        rep_state = state
    pfns = clean_surls(pfns)
    for pfn in pfns:
        new_pfn = models.BadPFNs(path=str(pfn), account=account, state=rep_state, reason=reason, expires_at=expires_at)
        new_pfn = session.merge(new_pfn)
        new_pfn.save(session=session, flush=False)
    try:
        session.flush()
    except IntegrityError as error:
        raise exception.RucioException(error.args)
    except DatabaseError as error:
        raise exception.RucioException(error.args)
    except FlushError as error:
        if match('New instance .* with identity key .* conflicts with persistent instance', error.args[0]):
            raise exception.Duplicate('One PFN already exists!')
        raise exception.RucioException(error.args)
    return True
Add bad PFNs.

:param pfns: the list of new files.
:param account: The account who declared the bad replicas.
:param state: One of the possible states : BAD, SUSPICIOUS, TEMPORARY_UNAVAILABLE.
:param reason: A string describing the reason of the loss.
:param expires_at: Specify a timeout for the TEMPORARY_UNAVAILABLE replicas. None for BAD files.
:param session: The database session in use.

:returns: True is successful.
@transactional_session
def add_bad_pfns(pfns, account, state, reason=None, expires_at=None, session=None):
    '\n    Add bad PFNs.\n\n    :param pfns: the list of new files.\n    :param account: The account who declared the bad replicas.\n    :param state: One of the possible states : BAD, SUSPICIOUS, TEMPORARY_UNAVAILABLE.\n    :param reason: A string describing the reason of the loss.\n    :param expires_at: Specify a timeout for the TEMPORARY_UNAVAILABLE replicas. None for BAD files.\n    :param session: The database session in use.\n\n    :returns: True is successful.\n    '
    if isinstance(state, string_types):
        rep_state = BadPFNStatus[state]
    else:
        rep_state = state
    pfns = clean_surls(pfns)
    for pfn in pfns:
        new_pfn = models.BadPFNs(path=str(pfn), account=account, state=rep_state, reason=reason, expires_at=expires_at)
        new_pfn = session.merge(new_pfn)
        new_pfn.save(session=session, flush=False)
    try:
        session.flush()
    except IntegrityError as error:
        raise exception.RucioException(error.args)
    except DatabaseError as error:
        raise exception.RucioException(error.args)
    except FlushError as error:
        if match('New instance .* with identity key .* conflicts with persistent instance', error.args[0]):
            raise exception.Duplicate('One PFN already exists!')
        raise exception.RucioException(error.args)
    return True