Is your feature request related to a problem? Please describe.
๋ก์ปฌ (csv / excel) ํ์ผ ๋ก๋์ ์ ์ฌ ๊ฐ/๋ถ ์ฌ๋ถ์ ๋ํ ์ ํจ์ฑ ์ฒดํฌ์ ๋ํด ๋ณด์์ ํด์ผํฉ๋๋ค.
Describe the solution you'd like
ํ์ผ์ ์
๋ก๋ ํ Preview ํ๋ฉด ๋ด ์์ ํด๋น CSV, ์ํธ๊ฐ ์ค๋ฅ๊ฐ ์๋ค๋ฉด ๊ฒฝ๊ณ ์์ด์ฝ/๋ฌธ๊ตฌ๊ฐ ๋
ธ์ถ๋์ด์ผ ํฉ๋๋ค.
๊ฒฝ๊ณ ๋ฌธ๊ตฌ ์ํฉ์ ์๋์ ๊ฐ์ต๋๋ค. (MT-31)
CSV ํ์ผ ๋ก๋์, (MT-33)
Describe alternatives you've considered
Additional context

@kyungtaak
ํ์ฌ ๋ฏธ๋ฆฌ๋ณด๊ธฐ์ ๊ฒฝ์ฐ๋ ์๋ฒ์์ ๋ด๋ ค์ฃผ๋๊ฒ์ ๋ฟ๋ ค์ฃผ๊ณ ์๋๋ฐ์.
์๋์ ์ผ์ด์ค์ ๋ํ result๋ ์ด๋ค ํํ๋ก ๋ด๋ ค์ค๋์?
Head ์ปฌ๋ผ์ ๋ณํฉ๋ cell์ด ์๋ ๊ฒฝ์ฐ: (Excel)
The first row contains merged cells. The new row is used as the head column.
์ค๋ณต ์ปฌ๋ผ๋ช : (Excel, CSV)
Duplicate column name not available.
๊ธด ์ปฌ๋ผ๋ช : (Excel, CSV)
Column names are allowed up to 50 characters.
๋น(๊ณต๋ฐฑ) ์ปฌ๋ผ: (Excel, CSV)
Empty column name is not allowed.
@brandon-wonjune
{
"fields": [{...}],
"data": [{...}],
"totalRows": 2,
"isParsable": {
"warning": "FV002",
"valid": false
}
}
Response์ isParsable ๊ฐ์ ์ถ๊ฐํ์ต๋๋ค.
isParsable.warning ๊ฐ์ ํตํด ๊ฒฝ๊ณ ๋ฌธ๊ตฌ๋ฅผ ๊ตฌ๋ถํด์ฃผ์๋ฉด ๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ฝ๋ ๋งคํ์ ์๋์ ๊ฐ์ด ํด์ฃผ์๋ฉด ๋ฉ๋๋ค.
FV002 : ๋ณํฉ๋ ์ปฌ๋ผ (Excel)
FV003 : ์ค๋ณต ์ปฌ๋ผ (Excel, CSV)
FV004 : ๊ธด ์ปฌ๋ผ (Excel, CSV)
FV005 : ๋น ์ปฌ๋ผ (Excel, CSV)
+(์ถ๊ฐ) FV001 : ํค๋ ์์ ๋ก์ฐ ์๊ฐ ๋ค๋ฅธ ๊ฒฝ์ฐ (์ผ๋ฐ์ ์ธ ๊ฒฝ๊ณ )
์๋ฒ๋จ ๋ก์ง์ด ์ ์ฉ๋ ๋ธ๋์น๋ f#1057-enhance_ingest_validation ์ ๋๋ค.
๋ฉ์ธ์ง ๋ค๊ตญ์ด๋ฅผ UI๋จ์์ ์ฒ๋ฆฌํ๊ณ ์์ด์ ์์ ๊ฐ์ด ์ฝ๋๊ฐ์ ๋ฆฌํดํ๊ฒ ํ๋๋ฐ์,
ํน์ ๋ ํ์ํ์ ๋ด์ฉ ์๋ค๋ฉด ๋ง์ํด์ฃผ์ธ์~
@alchan-lee
Q1. ๊ธด ์ปฌ๋ผ์ warning์ FV004๊ฐ ์ ๋ฌ๋๋๊ฒ ํ์ธํ์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ๋๋จธ์ง 002,003,005๋ ์ ๋ฌ๋์ง ์๊ณ ์์ต๋๋ค.



์๋ ํ์ผ์ ํ
์คํธ ํ ํ์ผ์
๋๋ค.
แแ
งแผแแ
กแธ1.xlsx
แแ
ตแซ.xlsx
แแ
ฎแผแแ
ฉแจ.xlsx
FV001์ FV005์ ์ด๋ค ์ฐจ์ด๊ฐ ์๋์?
Q2. ๊ทธ๋ฆฌ๊ณ ๊ธฐ์กด์ ๋ก์ง์ ๋ชจ๋ ์ํธ๋ฅผ ์กฐํํ์ง ์๊ณ ์ ํํ ์ํธ๋ง ์กฐํํ๋ api๋ฅผ ์ฌ์ฉํ๊ณ ์์์ต๋๋ค. (์์
ํ์ผ์ ๊ฒฝ์ฐ)
api/datasources/file/{fileName}/data?limit=100&firstHeaderRow=true&sheet=%EC%8B%9C%ED%8A%B81
๊ทธ๋ฐ๋ฐ ๋ณ๊ฒฝ๋ ๊ธฐํ์ ํ์ธํด๋ณด๋ฉด ์ด๊ธฐ์ ํ์ผ์ ์
๋ก๋์ ์์ฒ๋ผ ๋ฌธ์ ๊ฐ ์๋ ์ปฌ๋ผ์ด ์กด์ฌํ๋ ์ํธ๋ง๋ค ์๋ฌ ์์ด์ฝ์ ํ์ํด ์ค์ผ๋ฉ๋๋ค.
๊ทธ๋ด๊ฒฝ์ฐ ๊ธฐ์กด api๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉํ๋ค๋ฉด sheet์ ๊ฐฏ์ ๋งํผ api ์กฐํ๋ฅผ ์์ฒญํด์ ui์ ํ์ํด์ฃผ๋ฉด ๋๋๊ฑด์ง, ์๋๋ฉด ์๋ก api ๋ณ๊ฒฝ์ด ์์ ์์ ์ธ๊ฐ์?
@brandon-wonjune
ํ์ธ์ด ๋ฆ์ด์ง์ ์ฃ์กํฉ๋๋ค.
์ฐ์ Q1์์ ๋ฌธ์์ฃผ์ ๊ฒฐํจ์ ๋ณ๊ฒฝํด์ ๋ฐ์ํด๋์์ต๋๋ค (f#1057-enhance_ingest_validation ๋ธ๋์น)
Q2์์ ๋ฌธ์์ฃผ์ ๋ด์ฉ์ sheet ๊ฐฏ์๋งํผ api ํธ์ถ์ ๋ญ๋น์ ์ด๊ณ ,
๋ณ๋์ api๋ฅผ ์ถ๊ฐํ๊ธฐ๋ณด๋ค๋ upload api์์ sheet๋ช
๋ฆฌํด์์ ์๋์ ๊ฐ์ object๋ก ๋ฆฌํด๋๋ฆฌ๋ ค๊ณ ํ๋๋ฐ์,
์ด๋ ๊ฒ ์งํํด๋ ๊ด์ฐฎ์ผ์ค๊น์?
(๊ธฐ์กด์๋ String ๋ฆฌ์คํธ๋ก ์ํธ๋ช
๋ง ๋ฆฌํดํ์์ต๋๋ค)
{
"sheets": {
"์ํธ1": {
"warning": "FV002",
"valid": false
},
"์ํธ2": {
"valid": true
}
}
}
@alchan-lee
๋ค, ๊ทธ๋ฌ๋ฉด ๋ณ๊ฒฝ๋ api๋ ์๋์ ํํ๋ก ์๋ํ๊ฒ ๋๋์?
์ด๊ธฐ ํ๋ฉด ์ง์ > file ์ ๋ก๋ > api ์กฐํ > ์ํธ๋ณ error ๋ฐ warning ์ํ ํ์ธ > ์ํธ ์ ํ > ์ํธ ์์ธ๋ฐ์ดํฐ ์กฐํ api
@brandon-wonjune
๋ค ๋ง์ต๋๋ค. ์์ ์ธ๊ธ๋๋ฆฐ ๋๋ก ๋ฆฌํด๋๋๋ก
sheet๋ช
์กฐํ api ๋ฐ๊ฟ์ ๋ธ๋์น์ ๋ฐ์ํด๋์์ต๋๋ค.
๋ฌธ์ ๋๋ ๋ถ๋ถ ๋๋ ์ถ๊ฐ๊ฐ ํ์ํ ๋ถ๋ถ์ด ์๋ค๋ฉด ๋ง์ํด์ฃผ์ธ์~
@alchan-lee
์กฐํ ํ
์คํธ ์ค ์ง๋ฌธ ๋๋ฆฝ๋๋ค.
์ด๊ธฐ์ ํ์ผ ์
๋ก๋์ ๋ด๋ ค์ค๋ ์ ๋ณด ์ค 'sheets'๊ฐ ์๋๋ฐ์
๋น์ด์๊ฑฐ๋ ์ค๋ฅ๊ฐ ์๋ ์ํธ๊ฐ ํ๊ธฐ๋์ง ์๊ณ ์์ต๋๋ค.
// api
api/datasources/file/upload
// result
filePath: "/var/folders/08/8nxc3vnd2h75n7h060z4mzm80000gn/T//TEMP_FILE_e659d66e-e95d-4e90-bb98-ad415f08d3c8.xlsx"
filekey: "TEMP_FILE_e659d66e-e95d-4e90-bb98-ad415f08d3c8.xlsx"
sheets: ["Sheet1", "Sheet2", "Sheet3", "Sheet4"]
ํ์ฌ๋ ์์ ๊ฐ์ ํํ๋ก ๋ด๋ ค์ค๋๋ฐ์.
์ api๊ฐ ๋ง๋์?
@brandon-wonjune
์๋ ์ฒ๋ผ object๋ก ๋ฆฌํด๋๊ฒ ๋ณ๊ฒฝํด๋๊ฑด๋ฐ์.. ใ
ใ
๋ง์ํ์ result ๊ฐ์ sheets๊ฐ List ํํ๋ก ๋ด๋ ค์ค๋ ๊ฒ์ ์์ ๋ฐฉ์์ ๋๋ค.
f#1057-enhance_ingest_validation ๋ธ๋์น๋ฅผ pull ๋ฐ์ ๋ณด์๋ฉด ๋ฉ๋๋ค.
{
"sheets": {
"Sheet1": {
"warning": "FV002",
"valid": false
},
"Sheet2": {
"valid": true
},
"์ํธ1": {
"warning": "FV005",
"valid": false
}
},
"filePath": "/var/folders/rx/h_xkznq92gv26b8x72hy0stw0000gn/T//TEMP_FILE_0dc9c331-027f-4acd-a8ae-559b70e46a2d.xlsx",
"filekey": "TEMP_FILE_0dc9c331-027f-4acd-a8ae-559b70e46a2d.xlsx"
}
@kyungtaak @AnnieHwang @brandon-wonjune
์ฒ์์ ์ด ์ด์๊ฐ ์ถ๋ฐํ ๊ฒ์ MT-31์ธ๋ฐ์
๋ณํฉ๋ ์ปฌ๋ผ์ ๋น๋กฏํด ์ ์ ๊ฐ ์ผ๋ฐ์ ์ผ๋ก ์ค์ํ๋ ์ฌํญ(๊ณต๋ฐฑ, ์ค๋ณต ๋ฑ)์ ๋ํด ๊ฒฝ๊ณ ๋ฅผ ์ฃผ๋๋ก ๊ธฐํํ์์ต๋๋ค.
๊ทธ๋ฌ๋ ๋ณธ ํ๋ฉด์์ ์ํธ ์๋ ์ปฌ๋ผ ์๊ฐ ๋ง์ ๊ฒฝ์ฐ ์ด์ ๋ํ ์ ํจ๊ฐ ์ฒดํฌ๋ฅผ ํ๋ ๊ณผ์ ์์ ํผํฌ๋จผ์ค ์ ํ๊ฐ ์ผ์ด๋ ๊ฐ๋ฅ์ฑ์ด ๋์ต๋๋ค.
๋๋ถ์ด ํ์ฌ ์ด ๋ค์ ์คํ
์์ ์ค๋ณต ์ปฌ๋ผ๋ช
์ ๋น๋กฏํ ์ปฌ๋ผ๋ช
์์ฒด๋ฅผ ์์ ํ ์ ์๋ ์ด์#1202๊ฐ ๋ฑ๋ก๋์ด ์์ต๋๋ค.
๋๋ฌธ์ ๋ณธ ํ๋ฉด์์๋ 1๋ฒ์ ๋ณํฉ ์ปฌ๋ผ๋ง ์ฒดํฌํ๊ณ 2,3,4๋ฒ์ ์ปฌ๋ผ๋ช
validation ์ฒดํฌ๋ #1202์ด์๋ฅผ ์งํํ๋ฉด์ configure the schema๋จ๊ณ์์ ์งํํ๋ฉด ์ด๋จ๊น ํฉ๋๋ค.
์๋๋ฉด ์ด ํ๋ฉด์์ 1์ฐจ์ ์ผ๋ก ์ปฌ๋ผ๋ช
์ ํจ์ฑ ์ฒดํฌ๋ฅผ ํ๊ณ ๋์ด์จ๋ค ํด๋ configure the schema๋จ๊ณ์์ ๋ค์ ํ๋ฒ ์ปฌ๋ผ ์ ํจ์ฑ์ ์ฒดํฌํด์ผ ํ๊ธฐ๋๋ฌธ์
๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ค๋ณต ์ปฌ๋ผ์ ๋ํ ์ด์๋ #1175์๋ ๋ฑ๋ก๋์ด ์๋๋ฐ์
configure the schema๋จ๊ณ์์ ๊ฐ์ ๋ฃฐ๋ก validation์ ์ฒดํฌํ๋ฉด ์ข์ ๋ฏ ํฉ๋๋ค.
A. ์ธ ์ ์๋ ์ปฌ๋ผ๋ช ์ด ์์ ๊ฒฝ์ฐ
a-1. 1์ ์ด์์ ํน์๋ฌธ์ ํฌํจ ASCII ๋ฌธ์(์ซ์ ๋๋ ์๋ฌธ ๋๋ ํ๊ธ) ํ์ฉ
a-2. ํน์๋ฌธ์๋ก๋ง ์ด๋ค์ง ๋ฌธ์์ด ๋ถ๊ฐ (์ !!@@##)
a-3. Unicode ๋ถ๊ฐ
๋ฌธ๊ตฌ: Column name contains an invalid character.
์ปฌ๋ผ๋ช ์ ์ฌ์ฉํ ์ ์๋ ๋ฌธ์์ด์ด ์์ต๋๋ค.B. ์ค๋ณต ์ปฌ๋ผ๋ช ์ผ ๊ฒฝ์ฐ
b-1. ๋์ผํ ๋ฌธ์์ด์ ์ปฌ๋ผ๋ช ๋ถ๊ฐ
b-2. ๋/์๋ฌธ์ ๊ตฌ๋ถ ์ํจ (์ Name, name์ ๋์ผ ๋ฌธ์์ด ์ทจ๊ธ)
๋ฌธ๊ตฌ: Duplicate column name not available.
๋์ผํ ์ปฌ๋ผ๋ช ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.C. ๊ธด ์ปฌ๋ผ๋ช
c-1. 1์ ์ด์ 50์ ๋ฏธ๋ง์ ๋ฌธ์์ด ํ์ฉ
๋ฌธ๊ตฌ: Column names are allowed up to 50 characters.
1์~50์ ์ด๋ด์ ์ปฌ๋ผ๋ช ์ผ๋ก ์์ฑํด์ฃผ์ธ์D. ๋น(๊ณต๋ฐฑ) ์ปฌ๋ผ
d-1. ๊ณต๋ฐฑ(null), ๋น ๋ฌธ์์ด ( ) ๋ถ๊ฐ
๋ฌธ๊ตฌ: Empty column name is not allowed.
๋น ์ปฌ๋ผ๋ช ์ ํ์ฉ๋์ง ์์ต๋๋ค.
@deidera08 @alchan-lee
๋ณ๊ฒฝ๋ api ํ์ธํ์์ต๋๋ค.
ํ๊ฐ์ง ๋ฌธ์์ฌํญ์ด ์์ต๋๋ค.
๋ง์ฝ sheet ์ ์๋ฌด๊ฒ๋ ์๋ ๊ฒฝ์ฐ๋ ์์ sheets ๋ด๋ถ์ ํ์๊ฐ ๋๊ณ ์์ง ์๋๋ฐ์.
์ด๋ฌํ ์ผ์ด์ค์๋ ๋ณ๋๋ก ui์์ ํ์๊ฐ ํ์ํ์ง ๋ฌธ์๋๋ฆฝ๋๋ค.
์๋๋ ํ
์คํธํ๊ณ ์๋ ํ์ผ์
๋๋ค.
Sheet2๊ฐ ํด๋น ์ผ์ด์ค์
๋๋ค.
default.xlsx

@alchan-lee
๊ทธ๋ฆฌ๊ณ ์๋ api์กฐํ์ firstHeaderRow: false ํ๋ผ๋ฉํฐ๊ฐ ์๋๊ฒฝ์ฐ isParsable์ด ๋์ด์ค๊ณ ์์ง ์์ต๋๋ค.
CSVํ์ผ๊ณผ xlxsํ์ผ ๋๋ค ๋์ผํ๊ฒ ๋ฐ์ํ๊ณ ์์ต๋๋ค.
@kyungtaak @alchan-lee ๊ธฐํ์๋ถ ๋ง์ฒ๋ผ ํด๋น ์ด์์์ ๋ณํฉ๋ ์ ๋ง ์ฒดํฌํ๊ณ #1175์์ ๋ฒจ๋ฆฌ๋ฐ์ด์ ์ฒ๋ฆฌ๋ฅผ ๋ฌถ์ด์ ์งํํ๋ฉด ๋ ๊ฒ ๊ฐ์์.
๊ทธ๋ฆฌ๊ณ ์๋ api์กฐํ์
firstHeaderRow: falseํ๋ผ๋ฉํฐ๊ฐ ์๋๊ฒฝ์ฐ isParsable์ด ๋์ด์ค๊ณ ์์ง ์์ต๋๋ค.
CSVํ์ผ๊ณผ xlxsํ์ผ ๋๋ค ๋์ผํ๊ฒ ๋ฐ์ํ๊ณ ์์ต๋๋ค.
@brandon-wonjune
์ด ๋ถ๋ถ์ firstHeaderRow: false์ผ๋๋ ํค๋๋ฅผ ๋ด๋ถ์ ์ผ๋ก ๋ง๋ค๊ณ ์์ด์ ๋ณ๋๋ก validation์ ์ํ๋ค ๋ณด๋
isParsable์ด ๋น ์ ธ ์์๋ค์.
์ผ๊ด์ฑ์ด ์์ด์ผ ํ ๋ฏ ํ๋ isParsable์ true๋ก ๋ด๋ ค์ค๋๋ก ๋ฐ์ํด๋์์ต๋๋ค.
@AnnieHwang @deidera08 @brandon-wonjune @kyungtaak
๊ทธ๋ผ ์ด ๋จ๊ณ์์๋ ์๋ฒ๋จ์์ ๋ณํฉ๋ ์
์ด ์๋์ง๋ง ํ์ธํ๋๋ก ํ๊ฒ ์ต๋๋ค.
100 ์ปฌ๋ผ์ง๋ฆฌ๋ก ํ ์คํธ ํด๋ดค์๋ ์ฑ๋ฅ์ ์ข ์ฐจ์ด๊ฐ ๋๊ธด ํ๋ค์.
@alchan-lee
๋ฐ๋ก ์๋ฒ์ชฝ์์ ๋ณํฉ๋ ์
์ด์ธ์ ์ํฉ์ ๋ํด valid๋ฅผ true๋ก ๋ด๋ ค์ฃผ์ค๊ฑด๊ฐ์?
์๋๋ฉด UI์์ ๋ณํฉ๋ ์
(FV002)๋ง ๋ค์๋จ๊ณ๋ฅผ ์ํํ ์ ์๋๋ก ํ๋ฉด๋๋์?
@brandon-wonjune
๋ค, ์ฒซ๋ฒ์งธ ๋ง์ํ์ ๋๋ก ์๋ฒ์ชฝ์์ ๋ณํฉ๋ ์
์ ๋นผ๊ณ ๋ valid๋ฅผ true๋ก ๋ด๋ฆฌ๊ฒ ์ต๋๋ค.
@deidera08 @AnnieHwang @brandon-wonjune
CSV ํ์ผ ์
๋ก๋ ์์ header์ null ๊ฐ์ด ํฌํจ๋๋ ๊ฒฝ์ฐ ํฌ๋ฆฌํฐ์ปฌํ ์ค๋ฅ๊ฐ ๋ฐ์ํด์
์์ ํ์ผ์ ์ฌ๋ฆด ์๊ฐ ์๊ฒ ๋๋๋ฐ์,
์ด ๊ฒฝ์ฐ์๋ ํ์ผ ์
๋ก๋๋ฅผ ํ๋ ๋จ๊ณ์์ validation์ด ๊ผญ ํ์ํ๊ธฐ ๋๋ฌธ์ ๋จ๊ฒจ๋๋๋ก ํ๊ฒ ์ต๋๋ค.
(์ฒดํฌ๋ฅผ ๊ผญ ํด์ผํ๋๋ฐ notification์ ๋บ ์ด์ ๋ ์์ ๊ฒ ๊ฐ์์์)
์ต์ข ์ ์ผ๋ก ์ด ์ด์์์ ์งํ๋๊ณ ์๋ ํ์ผ์ ์ ๋ก๋ํ๋ ์์ ์์ validation์
๋๊ฐ์ง๊ฐ ๋ฉ๋๋ค.
@alchan-lee
์ ์ฉํ์์ต๋๋ค.
์๋์ ๊ฐ์ด ๋ํ๋๊ฒ ๋ฉ๋๋ค.
CSV์ธ ๊ฒฝ์ฐ


excel์ธ ๊ฒฝ์ฐ

Most helpful comment
@brandon-wonjune
๋ค ๋ง์ต๋๋ค. ์์ ์ธ๊ธ๋๋ฆฐ ๋๋ก ๋ฆฌํด๋๋๋ก
sheet๋ช ์กฐํ api ๋ฐ๊ฟ์ ๋ธ๋์น์ ๋ฐ์ํด๋์์ต๋๋ค.
๋ฌธ์ ๋๋ ๋ถ๋ถ ๋๋ ์ถ๊ฐ๊ฐ ํ์ํ ๋ถ๋ถ์ด ์๋ค๋ฉด ๋ง์ํด์ฃผ์ธ์~