Dataset Preview의 CSV와 Excel 표시 문제
인용된 값 안의 줄바꿈 때문에 CSV 추론 실패
큰따옴표가 중첩되거나 인용된 값 안에 줄바꿈이 들어 있는 CSV는 일반 스키마 추론에서 인용 문자 오류가 나고 Schema Editor에서 유효한 스키마를 만들지 못할 수 있습니다. 여러 줄의 값을 하나의 레코드로 읽는 Spark CSV reader로 전환할 수 있습니다.
- CSV를 데이터셋에 올리고
Edit Schema를 선택합니다. Column과Quotes속성을 파일에 맞게 설정합니다.- 현재 parser의 검증 때문에 저장할 수 없으면
Save and Validate옆 메뉴의Save without Validating을 선택합니다. 이 단계에서는 열 정의를 먼저 저장합니다. Details > Schema > Edit에서 reader와 파싱 설정을 다음처럼 바꿉니다. 기존 열 정의와 다른 필요한 스키마 필드는 유지합니다.
{
"dataFrameReaderClass": "com.palantir.foundry.spark.input.DataSourceDataFrameReader",
"customMetadata": {
"format": "csv",
"options": {
"header": true,
"multiLine": true
}
}
}
multiLine은 인용된 값 안의 줄바꿈을 같은 값으로 읽게 합니다. 검증을 건너뛴 상태 자체가 문제 해결은 아니며 reader를 바꾼 뒤 미리보기에서 열과 레코드 경계가 올바른지 확인합니다.
파일마다 뒤쪽 열 수가 다른 경우
APPEND 등으로 여러 CSV를 모은 데이터셋에서 일부 파일의 열 수가 다르면 다음과 같은 오류가 날 수 있습니다.
Could not load preview: Encountered an error parsing the input CSV data. Make sure all data is correctly formatted.
Your dataset failed to validate on x rows.
불규칙한 행을 버려도 되는 경우에는 Edit schema > Parsing options > Ignore jagged rows를 선택할 수 있습니다. 행을 보존하면서 없는 뒤쪽 열만 null로 채우려면 아래의 위치 기반 스키마 조건을 충족해야 합니다.
위치 기반 보정의 조건
원하는 모든 열 이름과 자료형을 사용자가 정의할 수 있어야 합니다. 모든 CSV의 열 순서가 같고 부족한 열은 뒤쪽에서만 빠져야 합니다.
| 목표 스키마 | 허용하는 파일 열 | 허용하지 않는 파일 열 |
|---|---|---|
| a, b, c | a / a, b / a, b, c | b, a처럼 순서가 바뀐 열 |
| a, b, c, d | a / a, b / a, b, c / a, b, c, d | b, c, d / a, c, d / a, b, d처럼 중간이나 앞쪽이 빠진 열 |
예를 들어 매일 APPEND하는 CSV에 새로운 마지막 열을 추가했다면 과거 파일의 행에 그 마지막 열을 null로 채울 수 있습니다. 이름을 기준으로 열을 재배치하거나 임의의 스키마를 합치는 기능은 아닙니다. 원시 Parquet의 ParquetDataFrameReader가 제공하는 mergeSchema와 같은 기능이 CSV에 필요한 경우에는 사용자 정의 변환을 작성해야 합니다.
전체 열 스키마 지정
Details > Schema > Edit에서 fieldSchemaList에 필요한 열을 빠짐없이 넣고 reader를 DataSourceDataFrameReader로 바꿉니다. 다음은 a, b, c를 모두 INTEGER로 정의한 예시입니다. 기존 스키마에 필요한 다른 필드는 유지합니다.
이 JSON은 Dataset Preview의 Schema Editor에서 사용하는 설정입니다. REST API로 스키마를 추가할 때의 DatasetFieldSchema는 nullable에 불리언을 요구하므로, 아래의 nullable: null을 API 요청 값으로 그대로 사용하지 않습니다.
{
"fieldSchemaList": [
{
"type": "INTEGER",
"name": "a",
"nullable": null,
"userDefinedTypeClass": null,
"customMetadata": {},
"arraySubtype": null,
"precision": null,
"scale": null,
"mapKeyType": null,
"mapValueType": null,
"subSchemas": null
},
{
"type": "INTEGER",
"name": "b",
"nullable": null,
"userDefinedTypeClass": null,
"customMetadata": {},
"arraySubtype": null,
"precision": null,
"scale": null,
"mapKeyType": null,
"mapValueType": null,
"subSchemas": null
},
{
"type": "INTEGER",
"name": "c",
"nullable": null,
"userDefinedTypeClass": null,
"customMetadata": {},
"arraySubtype": null,
"precision": null,
"scale": null,
"mapKeyType": null,
"mapValueType": null,
"subSchemas": null
}
],
"dataFrameReaderClass": "com.palantir.foundry.spark.input.DataSourceDataFrameReader",
"customMetadata": {
"format": "csv",
"options": {
"multiLine": true,
"header": true,
"mode": "PERMISSIVE",
"enforceSchema": true
}
}
}
저장한 뒤 미리보기를 확인합니다. enforceSchema: true는 지정한 스키마를 위치 기준으로 적용합니다. 따라서 원천 파일의 순서가 바뀌면 이름을 알아서 맞추지 않습니다. PERMISSIVE는 부족한 값과 해석할 수 없는 필드를 null로 처리할 수 있으며 스키마보다 많은 값은 잘릴 수 있습니다. 목표 스키마에 모든 열을 포함한다는 전제와 실제 데이터 내용이 맞아야 합니다.
Excel에서 CSV 열이 한 칸에 몰려 보이는 경우
지역별 Excel 기본 구분자 때문에 다운로드한 파일의 값들이 한 열에 모여 보일 수 있습니다. Excel에서 구분자를 지정하여 열을 나눕니다.
- 파일을 열고 리본의
Data를 선택합니다. Data Tools에서Text to Columns를 선택합니다.Convert text to columns wizard에서Delimited를 고르고Next를 선택합니다.Delimiters에서 파일이 사용하는 쉼표, 세미콜론 또는 탭을 선택합니다.Next,Finish로 완료합니다.
이 절차는 Excel에서 값을 해석하여 표시하는 방법을 바꾸며 Foundry 데이터셋의 스키마를 수정하는 절차는 아닙니다.