회고

[개발일지] - 562

Happy Programmer 2025. 1. 15. 23:31

마이그레이션을 하기 위해 정해진 규칙에 맞춰서 여러개의 엑셀 파일에 있던 데이터를 정리했고

key값, title, type, link 순으로 일렬로 하나의 파일에 모아줬다.

 

막상 엑셀 파일을 등록하니 맵핑되지 않은 값들도 많이 보였는데

이 부분은 예상하지 못했지만 수동으로 지우라는 것은 말이 안될 것 같고

내부 로직을 추가해서 SFDC ID 값이 없는 경우(맵핑되지 않아서)

발송 로직을 중단하고 다음 row 발송으로 넘어가게 변경했다.

 

일단 쓸모없는 로그들을 다 지우고

개별적으로 성공, 통과 및 실패 로그만 찍히게 주석처리한 다음

드디어 마이그레이션을 시작했는데 성공적으로 잘 돌아가서 상당히 만족스러웠다.

 

하지만 갑작스럽게 에러가 발생헀는데

아래 console에 찍힌 것과 같이 Maximum size 초과 문제로

용량을 계산해보니 대충 50mb가 넘으면 api로도 전송이 되지 않는 것 같았다.

Salesforce 오류: [{"message":"; nested exception is: \n\tcommon.exception.ApiException: Maximum size of request reached. Maximum size of request is 52428800 bytes.","errorCode":"JSON_PARSER_ERROR"}]

 

검색해보니 청크로 보내는 방식이 있다고 하긴 하는데

20분정도 전송해서 절반쯤 처리했기 때문에 마이그레이션 데이터도 정리해야 하고

전체 데이터를 가지고 청크 테스트를 할 수 없기 때문에

결국 또 테스트용 엑셀도 추가해야 하고 작업이 복잡해졌는데

청크 처리를 ContentVersion으로는 진행할 수 없었다.

 

특징 ContentVersion Chatter REST API

최대 파일 크기 약 37.5MB (Base64 인코딩 후 50MB) 2GB
대상 엔드포인트 /services/data/vXX.X/sobjects/ContentVersion /services/data/vXX.X/connect/files
Base64 인코딩 필요 여부 필요 필요 없음 (원시 데이터 사용 가능)
레코드 연결 방식 자동으로 레코드와 연결 수동으로 ContentDocumentLink 생성 필요
주요 사용 사례 일반 파일 업로드 대용량 파일 업로드

 

일단 수십개가 되어버린 청크를 수동으로 지울 수 없어서 지우려고 하다가

contentversion은 수동 삭제가 지원되지 않아서 예전 과제할 때나 지웠던 방식으로

version에서 document Id를 추출한 다음 해당 id List로 조회된 document를 삭제해야 했다.

List<String> idList = new List<String>();
List<ContentVersion> cvList = [Select ContentDocumentId From ContentVersion Where FirstPublishLocationId = '문제의 ID'];

for(ContentVersion cv : cvList){
    idList.add(cv.ContentDocumentId);
}
List<ContentDocument> cdList = [Select Id From ContentDocument Where Id IN :idList];
delete cdList;

 

이후 50mb 초과되는 내용을 처리하기 위해서 이런저런 검색을 하다가

쓸데없이 청크처리라는 내용에 꽂혀서 이리저리 찾아봣는데

4시간정도 이것저것 시도해도 정상적으로 처리되는 것이 없었고

그냥 50mb가 넘으면 해당 id값을 출력하는 방식으로 해서 수동처리하기로 했고

하는 김에 id가 없는 값들을 따로 제목을 모아두고

에러가 발생할 경우에도 리스트에 모으는 방식으로 해서

최종적으로 완료되면 초과데이터 id 리스트, id 없는 제목 리스트, 에러 발생 id 리스트를 출력했다.

 

주간회의가 4시에 있어서 부랴부랴 주간 업무내역을 작성하고

회의가 끝나자마자 다시 마이그레이션 예외처리를 마루힌 다음

파일 마이그레이션을 마치고 나머지 대용량 파일 ID들은 따로 기록했다 내일 처리하기로 했다.

 

 

(1).백준 30008번 준영이의 등급은 준영이랑 전혀 관련없는 사람들의 등급을 출력해야 하는 문제로

인원수와 각각 등수가 있을 떄 등수를 모아서 한번에 출력해야 했기 때문에

등급을 출력하는 함수를 먼저 만들어준 다음 

인원수로 나누고 100을 곱한 값을 요청 조건에 따라 내림처리하고 함수에 넣은 결과를 모아서 출력했다.

const input = `100 9
4 11 23 40 60 77 89 96 100`.split('\n').map(el => el.split(' ').map(Number))

const result = []
const greadeCheck = (n) => {
    if(n <= 4){
        return 1
    }
    else if(n <= 11){
        return 2
    }
    else if(n <= 23){
        return 3
    }
    else if(n <= 40){
        return 4
    }
    else if(n <= 60){
        return 5
    }
    else if(n <= 77){
        return 6
    }
    else if(n <= 89){
        return 7
    }
    else if(n <= 96){
        return 8
    }
    else{
        return 9
    }
}

for(let i = 0 ; i < input[1].length ; i++){
    result.push(greadeCheck(Math.floor(input[1][i] * 100 / input[0][0])))
}

console.log(result.join(' '))