사용자 지정 분류자 작성 - AWS Glue

사용자 지정 분류자 작성

AWS Glue에서 데이터를 분류할 수 있도록 사용자 지정 분류자를 제공할 수 있습니다. You can create a custom classifier using a grok 패턴, XML 태그, JavaScript Object Notation(JSON) 또는 CSV(쉼표로 분리된 값)를 이용하여 사용자 지정 분류자를 생성할 수 있습니다. AWS Glue 크롤러가 사용자 지정 분류자를 호출합니다. 분류자가 데이터를 인식하면 크롤러에 데이터 분류 및 스키마를 반환합니다. 데이터가 내장된 분류자와 일치하지 않거나 크롤러가 생성한 테이블을 사용자 지정하기 원할 경우 사용자 지정 분류자를 정의해야 할 수도 있습니다.

AWS Glue 콘솔을 사용한 분류자 생성에 대한 자세한 내용은 AWS Glue 콘솔에서 분류자 관련 작업을 참조하십시오.

AWS Glue는 사용자가 지정한 순서대로 내장된(기본) 분류자에 앞서 사용자 지정 분류자를 실행합니다. 크롤러가 데이터와 일치하는 분류자를 찾으면, 사용자의 AWS Glue Data Catalog에 작성되는 테이블 정의에 분류 문자열과 스키마를 사용합니다.

Grok 사용자 지정 분류자 작성

Grok는 텍스트 데이터의 패턴 일치 구문 분석에 사용하는 도구입니다. Grok 패턴은 한 번에 한 줄씩 데이터를 일치시킬 때 사용하는 명명된 정규식(regex) 세트입니다. AWS Glue는 grok 패턴을 사용하여 사용자 데이터의 스키마를 추정합니다. Grok 패턴과 사용자 데이터가 일치하는 경우 AWS Glue는 이 패턴을 사용해 데이터의 구조를 결정하고 이를 필드로 매핑합니다.

AWS Glue는 많은 기본 패턴을 제공하지만, 사용자가 직접 정의할 수도 있습니다. 기본 패턴을 사용하여 grok 패턴을 생성하거나 사용자 지정 분류자 정의에서 패턴을 사용자 지정할 수 있습니다. 사용자 지정 텍스트 파일 형식을 분류할 수 있도록 grok 패턴을 조정할 수 있습니다.

참고

AWS Glue grok 사용자 지정 분류자는 AWS Glue Data Catalog에서 생성된 테이블에 대해 GrokSerDe 직렬화 라이브러리를 사용합니다. AWS Glue Data Catalog를 Amazon Athena, Amazon EMR 또는 Redshift Spectrum에 사용하려는 경우 이러한 서비스에 대한 설명서에서 GrokSerDe 지원에 대한 정보를 확인하세요. 현재는 Amazon EMR 및 Redshift Spectrum에서 GrokSerDe로 생성된 테이블을 쿼리할 때 문제가 발생할 수 있습니다.

다음은 grok 패턴 구성 요소의 기본적인 구문입니다.

%{PATTERN:field-name}

명명된 PATTERN과 일치하는 데이터를 string이라는 기본 데이터 유형을 가진 스키마의 field-name 열로 매핑합니다. 선택적으로, 필드의 데이터 형식을 결과 스키마에서 byte, boolean, double, short, int, long 또는 float로 캐스트할 수 있습니다.

%{PATTERN:field-name:data-type}

예를 들면, num 필드를 int 데이터 유형으로 캐스트하기 위해 이 패턴을 사용할 수 있습니다.

%{NUMBER:num:int}

패턴을 다른 패턴으로 구성할 수 있습니다. 예를 들어 월, 해당 월의 날, 시간(예: Feb 1 06:25:43)의 패턴으로 정의되는 SYSLOG 타임스탬프의 패턴이 있을 수 있습니다. 이 데이터에서 다음 패턴을 정의할 수 있습니다.

SYSLOGTIMESTAMP %{MONTH} +%{MONTHDAY} %{TIME}
참고

Grok 패턴은 한 번에 한 줄씩만 처리할 수 있습니다. 여러 줄로 된 패턴을 지원하지 않습니다. 또 패턴 내부의 줄 바꿈도 지원하지 않습니다.

AWS Glue의 사용자 지정 분류자 값

Grok 분류자를 정의할 때 사용자 지정 분류자를 생성하기 위해 AWS Glue에 다음 값을 제공합니다.

이름

분류자의 이름.

Classification

special-logs 같이 분류되는 데이터의 형식을 설명하기 위해 작성하는 텍스트 문자열입니다.

Grok 패턴

일치 여부를 결정하기 위해 데이터 스토어에 적용하는 패턴 세트입니다. 이 패턴은 AWS Glue 기본 패턴 및 사용자가 정의한 사용자 지정 패턴입니다.

다음은 grok 패턴의 예입니다.

%{TIMESTAMP_ISO8601:timestamp} \[%{MESSAGEPREFIX:message_prefix}\] %{CRAWLERLOGLEVEL:loglevel} : %{GREEDYDATA:message}

데이터가 TIMESTAMP_ISO8601와 일치하면 스키마 열인 timestamp가 생성됩니다. 동작은 예제의 다른 명명 패턴과 유사합니다.

사용자 지정 패턴

선택적으로 사용자가 정의한 사용자 지정 패턴입니다. 사용자 데이터를 분류하는 grok 패턴이 이 패턴을 참조합니다. 데이터에 적용되는 grok 패턴에서 이런 사용자 지정 패턴을 참조시킬 수 있습니다. 각 사용자 지정 구성 요소 패턴은 별개 줄로 구성되어 있어야 합니다. 정규식(regex) 구문을 사용하여 패턴을 정의합니다.

다음은 사용자 지정 패턴 사용에 대한 예입니다.

CRAWLERLOGLEVEL (BENCHMARK|ERROR|WARN|INFO|TRACE) MESSAGEPREFIX .*-.*-.*-.*-.*

첫 번째 사용자 지정 명명 패턴인 CRAWLERLOGLEVEL은 데이터가 열거된 문자열 중 하나와 일치할 때 일치됩니다. 두 번째 사용자 지정 패턴인 MESSAGEPREFIX은 메시지 접두사 문자열과 일치를 시도합니다.

AWS Glue는 계속해서 생성 시간, 마지막 업데이트 시간, 분류자 버전을 추적합니다.

AWS Glue 기본 설정 패턴

AWS Glue는 사용자 지정 분류자 구축에 사용할 수 있는 많은 범용 패턴을 제공합니다. 분류자 정의의 grok pattern에 명명 패턴을 추가합니다.

다음 목록은 각 패턴이 한 줄씩 구성되어 있습니다. 각 줄의 패턴 이름에는 정의가 적용됩니다. 정규식(regex) 구문은 패턴을 정의하는 데 사용됩니다.

#<noloc>&GLU;</noloc> Built-in patterns USERNAME [a-zA-Z0-9._-]+ USER %{USERNAME:UNWANTED} INT (?:[+-]?(?:[0-9]+)) BASE10NUM (?<![0-9.+-])(?>[+-]?(?:(?:[0-9]+(?:\.[0-9]+)?)|(?:\.[0-9]+))) NUMBER (?:%{BASE10NUM:UNWANTED}) BASE16NUM (?<![0-9A-Fa-f])(?:[+-]?(?:0x)?(?:[0-9A-Fa-f]+)) BASE16FLOAT \b(?<![0-9A-Fa-f.])(?:[+-]?(?:0x)?(?:(?:[0-9A-Fa-f]+(?:\.[0-9A-Fa-f]*)?)|(?:\.[0-9A-Fa-f]+)))\b BOOLEAN (?i)(true|false) POSINT \b(?:[1-9][0-9]*)\b NONNEGINT \b(?:[0-9]+)\b WORD \b\w+\b NOTSPACE \S+ SPACE \s* DATA .*? GREEDYDATA .* #QUOTEDSTRING (?:(?<!\\)(?:"(?:\\.|[^\\"])*"|(?:'(?:\\.|[^\\'])*')|(?:`(?:\\.|[^\\`])*`))) QUOTEDSTRING (?>(?<!\\)(?>"(?>\\.|[^\\"]+)+"|""|(?>'(?>\\.|[^\\']+)+')|''|(?>`(?>\\.|[^\\`]+)+`)|``)) UUID [A-Fa-f0-9]{8}-(?:[A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12} # Networking MAC (?:%{CISCOMAC:UNWANTED}|%{WINDOWSMAC:UNWANTED}|%{COMMONMAC:UNWANTED}) CISCOMAC (?:(?:[A-Fa-f0-9]{4}\.){2}[A-Fa-f0-9]{4}) WINDOWSMAC (?:(?:[A-Fa-f0-9]{2}-){5}[A-Fa-f0-9]{2}) COMMONMAC (?:(?:[A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2}) IPV6 ((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)? IPV4 (?<![0-9])(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))(?![0-9]) IP (?:%{IPV6:UNWANTED}|%{IPV4:UNWANTED}) HOSTNAME \b(?:[0-9A-Za-z][0-9A-Za-z-_]{0,62})(?:\.(?:[0-9A-Za-z][0-9A-Za-z-_]{0,62}))*(\.?|\b) HOST %{HOSTNAME:UNWANTED} IPORHOST (?:%{HOSTNAME:UNWANTED}|%{IP:UNWANTED}) HOSTPORT (?:%{IPORHOST}:%{POSINT:PORT}) # paths PATH (?:%{UNIXPATH}|%{WINPATH}) UNIXPATH (?>/(?>[\w_%!$@:.,~-]+|\\.)*)+ #UNIXPATH (?<![\w\/])(?:/[^\/\s?*]*)+ TTY (?:/dev/(pts|tty([pq])?)(\w+)?/?(?:[0-9]+)) WINPATH (?>[A-Za-z]+:|\\)(?:\\[^\\?*]*)+ URIPROTO [A-Za-z]+(\+[A-Za-z+]+)? URIHOST %{IPORHOST}(?::%{POSINT:port})? # uripath comes loosely from RFC1738, but mostly from what Firefox # doesn't turn into %XX URIPATH (?:/[A-Za-z0-9$.+!*'(){},~:;=@#%_\-]*)+ #URIPARAM \?(?:[A-Za-z0-9]+(?:=(?:[^&]*))?(?:&(?:[A-Za-z0-9]+(?:=(?:[^&]*))?)?)*)? URIPARAM \?[A-Za-z0-9$.+!*'|(){},~@#%&/=:;_?\-\[\]]* URIPATHPARAM %{URIPATH}(?:%{URIPARAM})? URI %{URIPROTO}://(?:%{USER}(?::[^@]*)?@)?(?:%{URIHOST})?(?:%{URIPATHPARAM})? # Months: January, Feb, 3, 03, 12, December MONTH \b(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)\b MONTHNUM (?:0?[1-9]|1[0-2]) MONTHNUM2 (?:0[1-9]|1[0-2]) MONTHDAY (?:(?:0[1-9])|(?:[12][0-9])|(?:3[01])|[1-9]) # Days: Monday, Tue, Thu, etc... DAY (?:Mon(?:day)?|Tue(?:sday)?|Wed(?:nesday)?|Thu(?:rsday)?|Fri(?:day)?|Sat(?:urday)?|Sun(?:day)?) # Years? YEAR (?>\d\d){1,2} # Time: HH:MM:SS #TIME \d{2}:\d{2}(?::\d{2}(?:\.\d+)?)? # TIME %{POSINT<24}:%{POSINT<60}(?::%{POSINT<60}(?:\.%{POSINT})?)? HOUR (?:2[0123]|[01]?[0-9]) MINUTE (?:[0-5][0-9]) # '60' is a leap second in most time standards and thus is valid. SECOND (?:(?:[0-5]?[0-9]|60)(?:[:.,][0-9]+)?) TIME (?!<[0-9])%{HOUR}:%{MINUTE}(?::%{SECOND})(?![0-9]) # datestamp is YYYY/MM/DD-HH:MM:SS.UUUU (or something like it) DATE_US %{MONTHNUM}[/-]%{MONTHDAY}[/-]%{YEAR} DATE_EU %{MONTHDAY}[./-]%{MONTHNUM}[./-]%{YEAR} DATESTAMP_US %{DATE_US}[- ]%{TIME} DATESTAMP_EU %{DATE_EU}[- ]%{TIME} ISO8601_TIMEZONE (?:Z|[+-]%{HOUR}(?::?%{MINUTE})) ISO8601_SECOND (?:%{SECOND}|60) TIMESTAMP_ISO8601 %{YEAR}-%{MONTHNUM}-%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE}? TZ (?:[PMCE][SD]T|UTC) DATESTAMP_RFC822 %{DAY} %{MONTH} %{MONTHDAY} %{YEAR} %{TIME} %{TZ} DATESTAMP_RFC2822 %{DAY}, %{MONTHDAY} %{MONTH} %{YEAR} %{TIME} %{ISO8601_TIMEZONE} DATESTAMP_OTHER %{DAY} %{MONTH} %{MONTHDAY} %{TIME} %{TZ} %{YEAR} DATESTAMP_EVENTLOG %{YEAR}%{MONTHNUM2}%{MONTHDAY}%{HOUR}%{MINUTE}%{SECOND} CISCOTIMESTAMP %{MONTH} %{MONTHDAY} %{TIME} # Syslog Dates: Month Day HH:MM:SS SYSLOGTIMESTAMP %{MONTH} +%{MONTHDAY} %{TIME} PROG (?:[\w._/%-]+) SYSLOGPROG %{PROG:program}(?:\[%{POSINT:pid}\])? SYSLOGHOST %{IPORHOST} SYSLOGFACILITY <%{NONNEGINT:facility}.%{NONNEGINT:priority}> HTTPDATE %{MONTHDAY}/%{MONTH}/%{YEAR}:%{TIME} %{INT} # Shortcuts QS %{QUOTEDSTRING:UNWANTED} # Log formats SYSLOGBASE %{SYSLOGTIMESTAMP:timestamp} (?:%{SYSLOGFACILITY} )?%{SYSLOGHOST:logsource} %{SYSLOGPROG}: MESSAGESLOG %{SYSLOGBASE} %{DATA} COMMONAPACHELOG %{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{Bytes:bytes=%{NUMBER}|-}) COMBINEDAPACHELOG %{COMMONAPACHELOG} %{QS:referrer} %{QS:agent} COMMONAPACHELOG_DATATYPED %{IPORHOST:clientip} %{USER:ident;boolean} %{USER:auth} \[%{HTTPDATE:timestamp;date;dd/MMM/yyyy:HH:mm:ss Z}\] "(?:%{WORD:verb;string} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion;float})?|%{DATA:rawrequest})" %{NUMBER:response;int} (?:%{NUMBER:bytes;long}|-) # Log Levels LOGLEVEL ([A|a]lert|ALERT|[T|t]race|TRACE|[D|d]ebug|DEBUG|[N|n]otice|NOTICE|[I|i]nfo|INFO|[W|w]arn?(?:ing)?|WARN?(?:ING)?|[E|e]rr?(?:or)?|ERR?(?:OR)?|[C|c]rit?(?:ical)?|CRIT?(?:ICAL)?|[F|f]atal|FATAL|[S|s]evere|SEVERE|EMERG(?:ENCY)?|[Ee]merg(?:ency)?)

XML 사용자 지정 분류자 작성

XML는 파일에서 태그를 사용해 문서의 구조를 정의합니다. XML 사용자 지정 분류자의 경우 사용자가 행을 정의할 때 사용하는 태그 이름을 지정할 수 있습니다.

AWS Glue의 사용자 지정 분류자 값

XML 분류자를 정의할 때 사용자 지정 분류자를 생성하기 위해 AWS Glue에 다음 값을 제공합니다. 이 분류자의 분류 필드를 xml으로 설정합니다.

이름

분류자의 이름.

행 태그

XML 문서의 테이블 행을 정의하는 XML 태그 이름입니다. 꺾쇠 괄호 < >는 사용하지 않습니다. 이름은 태그에 대한 XML 규칙을 따라야 합니다.

참고

행 데이터가 포함된 요소는 자기 복제를 하는 비어 있는 요소가 될 수 없습니다. 예를 들어 이 빈 요소는 AWS Glue에서 구문 분석되지 않습니다.

<row att1=”xx” att2=”yy” />

비어 있는 요소를 다음과 같이 작성할 수 없습니다.

<row att1=”xx” att2=”yy”> </row>

AWS Glue는 계속해서 생성 시간, 마지막 업데이트 시간, 분류자 버전을 추적합니다.

예를 들어 다음과 같은 XML 파일이 있다고 가정하겠습니다. 작성자와 제목 열만 포함된 AWS Glue 테이블을 생성하려면 AWS Glue 콘솔에서 Row tag(행 태그)AnyCompany인 분류자를 생성합니다. 그런 다음 이 사용자 지정 분류자를 사용하는 크롤러를 추가해 실행합니다.

<?xml version="1.0"?> <catalog> <book id="bk101"> <AnyCompany> <author>Rivera, Martha</author> <title>AnyCompany Developer Guide</title> </AnyCompany> </book> <book id="bk102"> <AnyCompany> <author>Stiles, John</author> <title>Style Guide for AnyCompany</title> </AnyCompany> </book> </catalog>

JSON 사용자 지정 분류자 작성

JSON은 데이터 교환 형식입니다. 이름 값 쌍이나 순서가 지정된 값 목록을 가진 데이터 구조를 정의합니다. JSON 사용자 지정 분류자의 경우 데이터 구조에 JSON 경로를 지정해 사용자 테이블의 스키마를 정의할 수 있습니다.

AWS Glue의 사용자 지정 분류자 값

JSON 분류자를 정의할 때 사용자 지정 분류자를 생성하기 위해 AWS Glue에 다음 값을 제공합니다. 이 분류자의 분류 필드를 json으로 설정합니다.

이름

분류자의 이름.

JSON 경로

테이블 스키마 정의에 사용하는 객체를 가리키는 JSON 경로입니다. JSON 경로 작성 시 점이나 대괄호를 사용할 수 없습니다. 다음의 연산자가 지원됩니다:

연산자 설명
$ JSON 객체의 루트 요소입니다. 모든 경로 표현식은
* 와일드카드 문자로 시작됩니다. JSON 경로의 경우 위치와 무관하게 이름이나 숫자를 사용해야 합니다.
.<name> 점으로 표기된 하위 필드. JSON 객체의 하위 필드를 지정합니다.
['<name>'] 괄호로 표기된 하위 필드. JSON 객체의 하위 필드를 지정합니다. 하위 필드 1개만 지정할 수 있습니다.
[<number>] 어레이 인덱스. 인덱스 별로 어레이 값을 지정합니다.

AWS Glue는 계속해서 생성 시간, 마지막 업데이트 시간, 분류자 버전을 추적합니다.

예 배열에서 레코드를 가져오는 데 JSON 분류자 사용

JSON 데이터가 레코드 배열이라고 가정하겠습니다. 예를 들어, 파일의 처음 몇 줄은 다음과 비슷할 수 있습니다.

[ { "type": "constituency", "id": "ocd-division\/country:us\/state:ak", "name": "Alaska" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:1", "name": "Alabama's 1st congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:2", "name": "Alabama's 2nd congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:3", "name": "Alabama's 3rd congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:4", "name": "Alabama's 4th congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:5", "name": "Alabama's 5th congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:6", "name": "Alabama's 6th congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:7", "name": "Alabama's 7th congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:ar\/cd:1", "name": "Arkansas's 1st congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:ar\/cd:2", "name": "Arkansas's 2nd congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:ar\/cd:3", "name": "Arkansas's 3rd congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:ar\/cd:4", "name": "Arkansas's 4th congressional district" } ]

기본 JSON 분류자를 사용하는 크롤러를 실행할 때는 스키마 정의에 전체 파일이 사용됩니다. JSON 경로를 지정하지 않기 때문에 크롤러는 데이터를 하나의 객체로 처리하며, 이것이 배열입니다. 예를 들어, 스키마의 모양은 다음과 같을 수 있습니다.

root |-- record: array

하지만 JSON 어레이의 각 레코드를 토대로 스키마를 생성하려면 사용자 지정 JSON 분류자를 생성하고 JSON 경로를 $[*]로 지정합니다. 이 JSON 경로를 지정하는 경우, 분류자는 어레이의 12개 레코드를 모두 조사해 스키마를 결정합니다. 그 결과로 생성된 스키마에는 다음 예제와 유사하게 각 객체의 필드가 분리되어 포함됩니다.

root |-- type: string |-- id: string |-- name: string
예 파일의 일부만을 검사하는 데 JSON 분류자 사용

JSON 데이터가 http://everypolitician.org/에서 가져온 예제 JSON 파일 s3://awsglue-datasets/examples/us-legislators/all/areas.json의 패턴을 따른다고 가정합니다. JSON 파일의 예제 객체는 다음과 같습니다.

{ "type": "constituency", "id": "ocd-division\/country:us\/state:ak", "name": "Alaska" } { "type": "constituency", "identifiers": [ { "scheme": "dmoz", "identifier": "Regional\/North_America\/United_States\/Alaska\/" }, { "scheme": "freebase", "identifier": "\/m\/0hjy" }, { "scheme": "fips", "identifier": "US02" }, { "scheme": "quora", "identifier": "Alaska-state" }, { "scheme": "britannica", "identifier": "place\/Alaska" }, { "scheme": "wikidata", "identifier": "Q797" } ], "other_names": [ { "lang": "en", "note": "multilingual", "name": "Alaska" }, { "lang": "fr", "note": "multilingual", "name": "Alaska" }, { "lang": "nov", "note": "multilingual", "name": "Alaska" } ], "id": "ocd-division\/country:us\/state:ak", "name": "Alaska" }

기본 JSON 분류자를 사용하는 크롤러를 실행할 때는 스키마를 생성하는 데 전체 파일이 사용됩니다. 그러면 다음과 같은 스키마가 생성될 수 있습니다.

root |-- type: string |-- id: string |-- name: string |-- identifiers: array | |-- element: struct | | |-- scheme: string | | |-- identifier: string |-- other_names: array | |-- element: struct | | |-- lang: string | | |-- note: string | | |-- name: string

하지만 "id" 객체만을 사용하는 스키마를 생성하려면 사용자 지정 JSON 분류자를 생성하고 JSON 경로를 $.id로 지정합니다. 그러면 스키마는 "id" 필드에만 토대를 둡니다.

root |-- record: string

이 스키마에서 추출한 데이터의 첫 몇 줄은 다음과 같습니다.

{"record": "ocd-division/country:us/state:ak"} {"record": "ocd-division/country:us/state:al/cd:1"} {"record": "ocd-division/country:us/state:al/cd:2"} {"record": "ocd-division/country:us/state:al/cd:3"} {"record": "ocd-division/country:us/state:al/cd:4"} {"record": "ocd-division/country:us/state:al/cd:5"} {"record": "ocd-division/country:us/state:al/cd:6"} {"record": "ocd-division/country:us/state:al/cd:7"} {"record": "ocd-division/country:us/state:ar/cd:1"} {"record": "ocd-division/country:us/state:ar/cd:2"} {"record": "ocd-division/country:us/state:ar/cd:3"} {"record": "ocd-division/country:us/state:ar/cd:4"} {"record": "ocd-division/country:us/state:as"} {"record": "ocd-division/country:us/state:az/cd:1"} {"record": "ocd-division/country:us/state:az/cd:2"} {"record": "ocd-division/country:us/state:az/cd:3"} {"record": "ocd-division/country:us/state:az/cd:4"} {"record": "ocd-division/country:us/state:az/cd:5"} {"record": "ocd-division/country:us/state:az/cd:6"} {"record": "ocd-division/country:us/state:az/cd:7"}

JSON 파일의 "identifier" 같이 중첩된 객체를 토대로 스키마를 생성하려면 사용자 지정 JSON 분류자를 생성하고 JSON 경로를 $.identifiers[*].identifier로 지정합니다. 이 스키마는 이전 예제와 유사하지만, JSON 파일에서 전혀 다른 객체에 토대를 두고 있습니다.

이런 스키마는 다음과 같습니다.

root |-- record: string

테이블에서 데이터의 첫 몇 줄은 스키마가 "identifier" 객체에 토대를 두고 있다는 점을 보여줍니다.

{"record": "Regional/North_America/United_States/Alaska/"} {"record": "/m/0hjy"} {"record": "US02"} {"record": "5879092"} {"record": "4001016-8"} {"record": "destination/alaska"} {"record": "1116270"} {"record": "139487266"} {"record": "n79018447"} {"record": "01490999-8dec-4129-8254-eef6e80fadc3"} {"record": "Alaska-state"} {"record": "place/Alaska"} {"record": "Q797"} {"record": "Regional/North_America/United_States/Alabama/"} {"record": "/m/0gyh"} {"record": "US01"} {"record": "4829764"} {"record": "4084839-5"} {"record": "161950"} {"record": "131885589"}

JSON 파일의 "name" 배열의 "other_names" 필드 같이 다른 중첩된 객체를 토대로 테이블을 생성하려면 사용자 지정 JSON 분류자를 생성하고 JSON 경로를 $.other_names[*].name로 지정합니다. 이 스키마는 이전 예제와 유사하지만, JSON 파일에서 전혀 다른 객체에 토대를 두고 있습니다. 이런 스키마는 다음과 같습니다.

root |-- record: string

이 테이블의 처음 몇 줄 데이터는 "name" 배열 내 "other_names" 객체의 데이터에 근거함을 보여줍니다.

{"record": "Alaska"} {"record": "Alaska"} {"record": "Аляска"} {"record": "Alaska"} {"record": "Alaska"} {"record": "Alaska"} {"record": "Alaska"} {"record": "Alaska"} {"record": "Alaska"} {"record": "ألاسكا"} {"record": "ܐܠܐܣܟܐ"} {"record": "الاسكا"} {"record": "Alaska"} {"record": "Alyaska"} {"record": "Alaska"} {"record": "Alaska"} {"record": "Штат Аляска"} {"record": "Аляска"} {"record": "Alaska"} {"record": "আলাস্কা"}

CSV 사용자 지정 분류자 작성

사용자 지정 CSV 분류기를 사용하면 사용자 지정 csv 분류기 필드의 각 열에 대한 데이터 유형을 지정할 수 있습니다. 콤마로 분리된 각 열의 데이터 유형을 지정할 수 있습니다. 데이터 유형을 지정하면 크롤러가 추론한 데이터 유형을 재정의하고 데이터가 적절하게 분류되도록 할 수 있습니다. 사용자 지정 분류기를 만들면 분류기를 다른 크롤러에 다시 사용할 수도 있습니다.

  • 헤더만 있는(데이터 없음) csv 파일의 경우, 정보가 충분하지 않기 때문에 이러한 파일은 UNKNOWN으로 분류됩니다. 열 제목 옵션에서 CSV에 '제목 포함'을 지정하고 데이터 유형을 제공하면 이러한 파일을 올바르게 분류할 수 있습니다.

사용자 지정 CSV 분류자를 사용하여 다양한 유형의 CSV 데이터 스키마를 추론할 수 있습니다. 분류자에 제공할 수 있는 사용자 지정 속성에는 구분 기호, 헤더에 대한 옵션, 데이터에서 특정 검증을 수행할 수 있는지 여부가 포함되어 있습니다.

AWS Glue의 사용자 지정 분류자 값

CSV 분류자를 정의할 때 분류자를 생성하기 위해 AWS Glue에 다음 값을 제공합니다. 이 분류자의 분류 필드를 csv으로 설정합니다.

이름

분류자의 이름.

열 구분 기호

행의 열 입력 항목 각각을 구분하는 것을 나타내기 위한 사용자 지정 기호입니다.

인용 기호

단일 열 값에 내용을 결합하는 것을 나타내기 위한 사용자 지정 기호입니다. 열 구분 기호와 달라야 합니다.

열 제목

열 제목을 CSV 파일에서 어떻게 탐지해야 하는지에 대한 행동을 표시합니다. 사용자 지정 CSV 파일에 열 제목이 포함되어 있는 경우에는 쉼표로 구분된 열 제목 목록을 입력합니다.

처리 옵션: 단일 열에서 파일 허용

오직 하나의 열만 포함하는 파일을 처리할 수 있도록 합니다.

처리 옵션: 열 값을 식별하기 전에 공백 트리밍

열 값의 유형을 식별하기 전에 값의 트리밍 여부를 지정합니다.

사용자 지정 데이터 유형 - 선택 사항

쉼표로 분리된 사용자 지정 데이터 유형을 입력합니다. CSV 파일의 사용자 지정 데이터 유형을 지정합니다. 사용자 지정 데이터 유형은 지원되는 데이터 유형이어야 합니다. 지원되는 데이터 유형은 “바이너리”, “부울”, “날짜”, “십진수”, “더블”, “플로트”, “정수”, “롱”, “쇼트”, “문자열”, “타임스탬프”입니다. 지원되지 않는 데이터 유형은 오류를 표시합니다.