JMP 19는 JMP 18에서 도입된 데이터 커넥터 기능을 확장하여 더 많은 데이터 소스에 대한 균일한 접근을 지원합니다. JMP 19는 내장 연결 유형을 추가하는 것 외에도, 사용자가 공개된 Python API를 통해 자체 연결 유형을 정의할 수 있도록 합니다. 내장 유형과 마찬가지로, 이러한 자체 연결 유형도 구성 관리 및 쿼리 빌더 통합을 포함한 데이터 커넥터 기능의 이점을 공유합니다. 또한 Python으로 구현되었기 때문에 기존 Python 라이브러리를 활용할 수 있습니다. 이 프레젠테이션에서는 해당 API를 설명하고, 관련 개념을 논의하며, 실제 작동 방식을 보여줍니다.
안녕하세요. 오늘은 JMP의 데이터 커넥터 프레임워크, 특히 JMP 19에서 파이썬을 사용하여 확장할 수 있는 방법에 대해 이야기하려고 합니다. JMP 18에서는 데이터 커넥터 프레임워크를 도입하여 ODBC와의 연결 기능을 개선했습니다. JMP 19에서는 이 기능을 더욱 확장할 예정입니다.
저희가 SaaS에 다시 연결하기 위해 이 프레임워크를 어떻게 활용하고 있는지, Snowflake에 대한 네이티브 연결을 어떻게 제공하고 있는지에 대한 이야기를 다른 곳에서 들으셨을 수도 있습니다. 또한 제가 곧 말씀드릴 이 Python API 프레임워크를 사용하여 Amazon S3 및 Microsoft SharePoint와의 연결을 구현하고 있는데, 이는 JMP에 기본적으로 포함되지는 않지만 JMP 마켓플레이스를 통해 배포될 예정입니다.
이번 발표에서는 몇 가지 사항을 다루고자 합니다. 우선, 자체 데이터 소스를 보유하고 있다면 JMP와 통합하는 것이 왜 유용한지 간략하게 설명드리겠습니다. 통합을 원한다면, 데이터 소스와의 연동 방법, JMP가 데이터 소스와 통신하기 위해 필요한 사항, 그리고 이를 위해 작성해야 할 코드에 대해 알아두는 것이 좋습니다. 특히, 어떤 코드를 작성해야 하는지 자세히 살펴보겠습니다.
마지막으로, 코드를 공유하는 방법에 대해 이야기해 보겠습니다. 여러분이 작성한 코드는 여러분에게는 유용하지만, 회사 내 다른 사람들도 사용하고 싶어 할 수 있습니다. 또한 전 세계의 다른 JMP 사용자들과 코드를 공유하고 싶을 수도 있습니다. 이러한 공유를 쉽게 하기 위해 파이썬을 선택했습니다. 파이썬에는 이미 사용 가능한 라이브러리가 많거나, 여러분이 직접 작성한 코드를 활용할 수 있기 때문입니다. 아마존 S3 및 마이크로소프트 SharePoint와의 연결도 이러한 방식으로 구현되었습니다. 기존 파이썬 라이브러리를 활용하여 코드를 래핑함으로써, 여러분에게도 더 쉬운 사용 경험을 제공할 수 있기를 바랍니다.
간편하게 사용할 수 있도록 설계했다는 점 외에도, 통합을 고려해 볼 만한 또 다른 이유는 바로 구성 관리 기능입니다. 사용자는 커넥터 편집기를 통해 연결을 설명하는 구성을 생성하고 편집할 수 있으며, 쿼리 빌더를 이용하면 그래픽 인터페이스를 통해 쿼리를 작성하고, 데이터를 필터링하고, 열을 선택하는 등 다양한 작업을 수행할 수 있습니다. 또한, 공동 작업도 가능합니다. 사용자가 생성한 연결과 구성은 추가 기능을 통해 내보내고 공유할 수 있습니다.
이 기능을 이전에 본 적이 없으시다면, 곧 제가 실제로 어떻게 작동하는지 보여드릴 때 더 자세히 보실 수 있을 겁니다. 하지만 그 전에, 모든 것이 어디에 위치하고 어떻게 연결되는지 이야기해 보겠습니다. 우선 데이터 소스가 있고, 이 데이터 소스가 JMP와 통신하도록 설정해야 합니다.
하지만 JMP에서 데이터라고 하면 데이터 테이블을 의미합니다. 이러한 테이블은 데이터 소스에서 바로 제공할 수 있는 경우도 있고, 약간의 처리가 필요한 경우도 있습니다. 예를 들어, 계층 구조로 된 JSON 데이터를 반환하는 웹 엔드포인트가 있다고 가정해 보겠습니다. 이 경우, 데이터 처리가 필요합니다. 하지만 JMP에서 데이터 테이블 형태로 제공될 수 있다면, 해당 데이터는 활용될 수 있습니다.
쿼리 빌더는 해당 데이터에 접근할 때 마치 MySQL이나 SQL Server와 같은 기존 데이터베이스처럼 데이터를 처리합니다. 데이터가 명명된 테이블로 구성되어 있고, 이러한 테이블들이 다시 명명된 스키마로 구성되어 있을 것으로 예상합니다.
하지만 여러분은 아마도 하나 이상의 데이터 소스를 가지고 있을 것입니다. 혹은 그렇지 않더라도, 데이터에 접근하는 방법은 여러 가지가 있을 것입니다. 사용자마다 다른 자격 증명을 사용할 수도 있고, 데이터가 있는 위치의 주소를 하드코딩하고 싶지 않을 수도 있습니다. 어떤 식으로든 여러 가지 옵션이 있을 것입니다. 이러한 옵션에 특정 값을 제공하면 구성이 생성됩니다. 그리고 이 구성을 사용하여 데이터 소스를 만들 수 있습니다. 이러한 구성은 데이터 커넥터 편집기를 통해 생성할 수 있습니다.
간략하게 설명드리자면, 그림은 이렇습니다. 하지만 이것을 코드로 어떻게 구현할까요? 한번 살펴보겠습니다. 저는 지금 JMP를 사용하고 있습니다. 이 창은 잠시 닫고 새롭게 시작해 보겠습니다. 왼쪽에는 몇 가지 데이터 커넥터 유형을 구현하는 코드가 있습니다. 유형은 JMP에 내장된 ODBC와 같은 것일 수도 있고, 로컬, 원격 또는 연결을 통한 SaaS 유형 중 하나일 수도 있습니다. Snowflake도 가능합니다. 하지만 어떤 유형이든 구현하려면 Python을 사용하는 것도 좋은 방법입니다.
맨 위에는 몇 가지 임포트가 있습니다. 특히 내장 JMP 모듈을 임포트했죠. 이 유틸리티 함수를 사용하면 함수가 호출되는 시점을 확인할 수 있습니다. 이 데모에서는 JMP가 코드를 호출하기 때문에 이 함수를 사용합니다. 코드를 직접 호출하는 경우는 많지 않지만, 코드 실행 과정을 이해하는 데 도움이 되도록 호출 시점을 추적하는 것이 중요합니다.
아래 코드가 바로 해당 타입을 구현하는 부분입니다. 좀 더 자세히 설명하기 전에 제가 가지고 있는 참고 자료를 살펴보겠습니다. 이 목록에 있는 여러 항목들은 제가 방금 보여드린 다이어그램과 여러 면에서 일치합니다. 옵션이 필요하므로, `jmp.DataConnectorType` 클래스를 서브클래싱하고 옵션을 정의하는 필드 속성을 정의하여 구현하겠습니다. 구성 정보를 데이터 소스로 변환해야 하므로, `jmp.DataConnector` 클래스를 서브클래싱하고 변환을 수행하는 `_do_as_data_source` 함수를 정의하겠습니다.
마지막으로 데이터 소스 자체가 있습니다. 이것도 서브클래스입니다. 스키마가 있는지, 테이블이 무엇인지, 특정 테이블의 데이터가 무엇인지 알려주는 함수를 정의할 것입니다. 이 데모에서는 다루지 않겠지만, 자동으로 정리되지 않는 리소스가 있는 경우(예: 이러한 동작이 없는 연결이 있는 경우)에는 Python의 특수한 이중 밑줄(_) 메서드를 사용하여 더 이상 참조되지 않을 때 해당 리소스를 정리해야 한다는 점을 기억해 두는 것이 유용합니다. JMP는 데이터 소스를 닫을 때 Python이 직접 정리하도록 처리하기 때문입니다.
이 점을 염두에 두고 코드를 다시 살펴보겠습니다. jmp.DataConnectorType을 상속하는 SimpleFolderConnectorType이 보입니다. 앞서 말했듯이 이 클래스에는 옵션이 있는 필드가 있습니다. 여기서 유일한 옵션은 "Folder"입니다.
이 경우, 여기서 말하는 '폴더'는 실제로 SimpleFolder 연결이 어떤 모습일지를 나타내는데, 바로 데이터 소스를 의미합니다. 이 데이터 소스는 제 로컬 파일 시스템에 있는 단일 폴더에 해당하며, 해당 폴더는 그 안에 있는 파일 형태로 데이터를 노출합니다.
시작하기 위해 "폴더"라는 변수가 있고, 이 변수의 값은 옵션을 설명하는 이 딕셔너리에서 `str | None` 유형입니다. 이는 선택적 문자열 값을 사용할 수 있음을 의미합니다. 다음으로, `SimpleFolderConnector`라는 구성 클래스가 있는데, 이는 `jmp.DataConnector`를 상속합니다. 이 클래스는 `_do_as_data_source` 함수를 정의하여 구성에서 데이터를 변환하거나 연결합니다.
우리는 내장 딕셔너리처럼 자체 인덱스를 사용하여 구성 값인 "폴더"에 접근할 수 있습니다. 만약 이 값이 "none"이라면, 즉 사용자가 기본값을 입력하지 않았다면, 오류 메시지를 표시하여 필수 값임을 알려줍니다.
마지막으로, 이를 데이터 소스로 변환하겠습니다. 데이터 소스 클래스는 목록의 마지막 항목입니다. 물론, 데이터 소스를 생성할 수 있어야 합니다. 초기화 함수를 정의합니다. 이 경우, 실제로 디렉토리인지 확인합니다. 왜냐하면 코드를 사용하는 사용자(본인 또는 다른 누구든)에게 오류가 있는지 알려주기 위함입니다. 데이터 소스를 생성할 때는 연결 시점에 확인하는 것이 좋습니다. 이 경우에는 실제로 연결할 필요는 없지만, 적어도 폴더가 존재하는지 확인할 수 있습니다.
다음으로 살펴볼 것은 `get-schemas`였습니다. 이 경우 데이터 소스는 스키마가 없는 방식입니다. 테이블에 직접 접근할 수 있으므로 `get-schemas`를 정의할 필요가 없으며, JMP는 데이터 소스가 스키마를 사용하지 않는다는 것을 자동으로 인식합니다.
하지만 테이블이 무엇인지 정의해야 합니다. 이 경우 스키마 매개변수를 받아야 하지만 사용하지 않으므로 무시하겠습니다. 그런 다음 파일을 살펴볼 것이므로 파일 이름을 지정하는 방법이 필요합니다. 이 경우에는 그냥 파일 이름만 사용하면 됩니다. 폴더를 순회하면서 폴더 안의 모든 파일의 이름을 반환합니다.
마지막으로 데이터 테이블을 가져와야 합니다. 이 마지막 테이블 열기 함수가 바로 그 역할을 합니다. 먼저 데이터가 저장된 파일의 경로를 재구성해야 합니다. 테이블 이름은 파일 이름에 폴더 이름이 추가된 형태인데, 이 테이블 이름을 가져와서 경로를 문자열로 반환합니다.
제가 방금 말씀드린 모델은 데이터 테이블을 반환하도록 되어 있는데, 그렇게 할 수 있습니다. 앞서 예시로 드렸던 웹 엔드포인트처럼 계층적인 JSON 형식의 데이터를 반환하는 경우가 있는데, 이런 데이터를 직접 데이터 테이블로 변환하거나 그대로 반환하는 것이 좋습니다.
하지만 이 경우에는 파일 시스템에서 접근하는 것이고, S3 및 SharePoint 추가 기능을 개발할 때에도 이러한 방식을 사용했으며, 다른 파일 기반 데이터 저장소에 접근하는 것에 대한 관심도 있었던 것으로 알고 있습니다. 따라서 파일을 직접 여는 것이 아니라, 이 문자열을 전달하는 방식으로 JMP가 파일을 열 수 있습니다.
이 기능은 파일이 비공개로 열리도록 하는 등의 작업을 처리합니다. 여기서 반환되는 데이터 테이블은 구현 세부 사항입니다. 사용자에게 직접 노출해서는 안 되는 부분입니다. 쿼리 빌더를 사용할 때는 중간 테이블이 나타나지 않고 최종 결과만 표시됩니다. 이 경우 JMP가 이 부분을 처리해 줍니다. 또한 이 방식을 사용하면 JMP가 테이블을 열 때 필요한 설정을 유지할 수 있습니다. 이 부분은 나중에 더 자세히 설명하겠습니다.
마지막으로, 여기에 `jmp.DataConnector.tie` 함수 호출이 있습니다. 이 함수는 타입 클래스와 커넥터 클래스라는 두 개의 인수를 받아 서로를 참조하도록 설정합니다. 현재는 어느 쪽도 서로를 참조하지 않지만, 맨 위에 있는 `DataConnectorType` 클래스가 JMP가 접근점으로 사용하는 클래스입니다. 타입은 연결을 구성하는 모든 코드와 정의를 포괄하는 개념입니다. 따라서 두 클래스는 서로를 참조해야 합니다.
마지막으로, 여기에 최종 유형 문자열이 무엇인지 나타내는 주석이 있습니다. DBC일 수도 있고, ODBC일 수도 있습니다. SAS Viya 또는 SAS Remote일 수도 있습니다. 이 경우 Python에서는 콜론(:)을 사용하여 함수 유형임을 나타냅니다. __main__은 JMP에서 직접 실행했기 때문에 모듈 이름입니다. 마지막으로 SimpleFolderConnectorType은 클래스 이름입니다.
실제로 어떻게 작동하는지 살펴보겠습니다. 데이터 커넥터 대화 상자를 열고 새 연결을 생성하면 데이터 커넥터 편집기가 열립니다. 유형을 Python으로 변경하면 나머지 문자열을 입력할 수 있는 공간이 나타납니다. 여기에 문자열을 입력해 보겠습니다.
이렇게 하면 "폴더" 옵션이 표시됩니다. 값이 없으므로 "없음"에 해당합니다. 이제 연결을 시도하고 이 함수와 저 함수를 호출해 보면 "폴더가 필요합니다"라는 오류 메시지가 표시됩니다.
자, 이제 실제로 데이터에 접근하기 위해 JMP에 포함된 샘플 가져오기 데이터를 사용해 보겠습니다. 바로 이 폴더입니다. 복사하겠습니다. 다시 보여드리겠습니다. 경로를 복사해서 JMP에 붙여넣습니다. 테스트 결과가 보이시죠? 이제 모든 것이 정상이니 연결을 진행하겠습니다.
이제 연결이 완료되었으니 여기에서 테이블 목록을 볼 수 있습니다. 실제로 이 테이블들은 여기에 있는 파일들에 해당합니다. 여기 Animals_L.txt 파일이 보이고, 여기에서도 다시 볼 수 있습니다. 로그를 살펴보면 이 로그 항목 함수가 유용하게 사용되었음을 알 수 있습니다. _do_as_data_source 함수가 여러 번 호출되었고, 테스트하는 동안 데이터 소스 초기화도 여러 번 수행되었음을 확인할 수 있습니다. 또한 get-tables 함수가 호출되어 이 목록을 다시 제공한 것도 볼 수 있습니다.
여기서 쿼리 빌더를 실행하면 어떤 열들이 있는지 확인할 수 있습니다. 쿼리를 작성하면서 열을 추가할 수도 있고, 필터링도 가능합니다. 예를 들어, 여러 시즌 중 두 시즌만 선택할 수 있습니다. SQL 쿼리를 보면 모든 데이터가 포함되는 것을 볼 수 있습니다. 쿼리를 실행하면 결과가 나타납니다.
이 모든 것이 어떻게 작동하는지 궁금하실 수도 있습니다. SQL 쿼리를 작성하고 SQL 코드를 실행했죠. 하지만 처음에 정의를 내릴 때는 SQL이라는 개념 자체가 거의 없었습니다. 이렇게 작동하는 이유는 우리가 테이블에 접근할 수 있는 경로를 제공했기 때문입니다. 그러면 JMP가 나머지를 처리해 줍니다. JMP는 내부적으로 SQLite라는 내장 데이터베이스를 사용하여 데이터를 노출하고 SQL 코드를 실행할 수 있도록 합니다. 예를 들어, 두 시즌만 볼 수 있도록 해주는 WHERE 절이 바로 그런 역할을 합니다.
좀 더 복잡한 파일을 살펴보겠습니다. 우리가 가장 좋아하는 Excel의 큰 클래스로 돌아가 보겠습니다. 다시 쿼리 빌더를 엽니다. 이전에는 어떤 작업을 하기 전에 이 대화 상자가 나타나는 것을 볼 수 있습니다. 파일이 여러 개 있는 경우, 파일 내용을 지정하려면 프롬프트가 표시되어야 한다고 결정했습니다. JMP가 이 파일을 열려고 하면 가져오기 마법사에 필요한 정보를 입력하라는 메시지가 표시됩니다.
모든 게 좋아 보이니 가져오기를 클릭해 보겠습니다. 이제 이전처럼 열 이름과 스냅샷이 보입니다. 이제 가져오기를 클릭해 보겠습니다. 데이터가 가져와진 것을 확인할 수 있습니다. 혹시 매번 이 과정을 반복해야 하는지 궁금하실 수도 있는데, 답은 '아니요'입니다.
이 소스 스크립트를 살펴보겠습니다. 맨 위에는 예상대로 "새 SQL 쿼리"가 있습니다. 연결 정보도 있는데, 이 경우에는 데이터 커넥터에서 제공합니다. 연결 정보는 우리가 지정한 데이터 유형과 폴더를 참조하고 있습니다.
하지만 테이블을 자세히 살펴보면 '열기 설정'이라는 새로운 옵션이 있는 것을 볼 수 있습니다. '열기 설정'은 가져오기 마법사에서 지정한 내용을 그대로 가져옵니다. 특히, 기본 대형 클래스 테이블의 소스 스크립트에서 열기 명령에 전달된 추가 인수를 가져와 여기에 제공합니다.
이렇게 하면, 다시 실행했을 때 모든 것이 제대로 열려 있고 좋아 보입니다. 만약 설정에서 표준과 다른 작업을 수행했거나, 예를 들어 나중 열부터 시작해야 했던 경우라면, 그 내용이 여기에 그대로 반영될 것입니다. 로그를 보면 모든 것이 다시 시작된 것을 알 수 있습니다. _do_as_data_source 함수를 다시 호출했고, 테이블 목록을 가져온 다음, 실제로 이 테이블을 다시 열었습니다.
이게 기본입니다. 이건 좀 더 복잡해 보이죠. 하지만 단순히 더 복잡한 것뿐만 아니라, 기능도 좀 더 풍부합니다. 이건 다시 말하지만, 연결을 할 수 있는 최소한의, 가장 작은 버전입니다.
이제 좀 더 보기 좋아졌죠. 단순한 폴더 커넥터 대신, 완전한 기능을 갖춘 폴더 커넥터를 사용하게 되었습니다. 필드 정의가 훨씬 더 복잡해졌지만, 이전과 비슷한 구성 요소들을 기반으로 만들어졌습니다.
우선 이 경우에 추가되는 것은 `jmp.DataConnectoGroupedFields`의 사용입니다. 이를 통해 필드를 서로 다른 그룹으로 지정할 수 있습니다. 이는 데이터 커넥터 편집기에서 필드가 표시되는 방식에 영향을 미칩니다. ODBC의 경우 옵션이 여러 그룹으로 묶여 있는데, 파이썬에서도 동일한 기능을 사용할 수 있습니다.
각 그룹은 jmp.DataConnectorGroupedFields에 전달되는 이 목록의 쌍을 지정합니다. 첫 번째는 이름이고, 두 번째는 이전과 마찬가지로 옵션 이름과 필드 정의가 포함된 딕셔너리입니다. 필드 정의에는 여전히 str | None과 같은 유형이 포함되어 있습니다. 하지만 이 필드 정의를 jmp.DataConnectorField로 감싸고 있는데, 이 필드는 여러 번 사용되고 길이가 다소 길기 때문에 별칭을 지정했습니다. 이를 통해 예를 들어 옵션 이름 위에 마우스를 올렸을 때 데이터 커넥터 편집기에 표시될 툴팁과 같은 추가 정보를 지정할 수 있습니다.
기본값을 지정할 수 있습니다. 또한 데이터 커넥터 편집기에 표시될 이름을 지정할 수 있는데, 이 이름은 JSL에서 사용될 구성 파일에 사용되는 이름과 다를 수 있습니다. 예를 들어 JMP에서 ODBC를 사용할 때 이 기능을 활용하여 옵션 이름을 지역화하거나 JSL에서 기본적으로 사용되는 문자열보다 더 나은 문자열을 제공합니다. 즉, JSL 스타일의 이름을 사용하는 것입니다.
여기서 "Ordner"는 독일어로 폴더를 뜻하는 단어인 것 같습니다. 곧 알게 되실 겁니다. 데이터 소스를 보는 방식이 바뀐 점은 여전히 폴더를 기반으로 하지만, 선택적으로 스키마도 지원한다는 것입니다. 이 경우, 이전처럼 데이터를 보는 대신, 여기에 제공된 폴더의 하위 폴더를 스키마로, 그 안에 있는 파일을 데이터 테이블로 간주하는 새로운 방식으로 데이터를 볼 수 있는 옵션이 제공됩니다.
테이블 이름과 기본 파일 간의 매핑 방식을 특정 확장자로 제한하고 일부를 잘라내는 방식으로 다양하게 살펴보는 또 다른 옵션이 있습니다.
연결 시 데이터 소스로 변환하는 과정은 비슷하지만 옵션이 더 많아져서 약간 더 복잡합니다. 여전히 "폴더"를 확인하지만, 이 확장 옵션도 확인합니다. 오류가 발생하면 모든 데이터를 새 데이터 소스로 전달합니다.
새로운 데이터 소스는 먼저 폴더를 확인하고 다른 옵션도 설정합니다. 스키마도 제공하는데, 스키마를 사용하는 경우 폴더 안의 하위 폴더를 살펴보는 비슷한 코드를 사용하게 됩니다. 하위 폴더의 디렉터리 이름을 가져와서 그 이름을 스키마 이름으로 사용합니다.
하지만 스키마를 사용하지 않는 경우, 즉 새로운 옵션을 설정하지 않은 경우에는 None을 반환합니다. 이전에는 스키마를 정의하거나 `get-schemas`를 사용하지 않았지만, 여기서는 선택적으로 함수를 정의할 수 없으므로 대신 "스키마가 없습니다"라는 의미로 None을 반환할 수 있습니다. 즉, 스키마를 사용하지 않는다는 뜻입니다.
`Get-tables`는 이전과 비슷한 개념입니다. 궁극적으로는 여러 파일의 이름을 가져오는 것이죠. 하지만 옵션에 따라 몇 가지 다른 방식으로 가져올 수 있습니다. 디렉터리를 가져올 수도 있고, 스키마에 따라 달라질 수도 있습니다. 심지어 스키마를 사용하는지 여부에 따라서도 달라집니다. 그런 다음 파일 이름을 가져오기 전에 필터링을 하거나, 확장자를 처리하는 등 더 복잡한 방법을 사용할 수도 있습니다.
마지막으로 데이터 테이블을 얻으려면 `get-schemas`와 `get-tables`의 과정을 역순으로 진행합니다. 경로를 재구성해야 하는데, 확장자를 다시 추가할 수도 있습니다. 하지만 이렇게 하면 관련 디렉터리는 가져오지 못하므로, 경로로 다시 반환하기 전에 파일 이름을 끝에 다시 붙여야 합니다. 이렇게 하면 경로가 문자열로 다시 반환됩니다. 이들을 연결하면 이전과 같이 형식 이름이 생성됩니다.
자, 한번 살펴보죠. 다시 참조할 수 있도록 스크롤을 올려볼게요. 이전처럼 여기서 유형을 설정해 보겠습니다. 툴팁과 함께 사용자 지정 이름이 표시된 것을 볼 수 있죠. 폴더 경로도 이전과 동일하게 사용할게요. 경로를 가져와 보겠습니다. 아니, 한 단계 더 올라가 보죠. 스키마 기능을 사용해 보겠습니다. 복사해 볼게요.
그럼 이제 하위 폴더를 스키마로 사용하고 싶다고 말할 수 있겠네요. 이 고급 옵션을 추가했으니 사용해 보겠습니다. 모든 게 제대로 보이는지 확인해 볼게요. 네, 연결됐습니다. 모든 창이 화면 중앙에 잘 보이도록 배치해 보겠습니다.
이제 왼쪽에 보이는 스키마는 사실 폴더 이름일 뿐입니다. 여기에 가져온 데이터가 있습니다. .txt 파일로 제한했음을 알 수 있습니다. 이전처럼 동물 예제를 다시 열어 보겠습니다. 데이터가 제대로 표시되고 모든 것이 정상적으로 작동합니다. 이전과 마찬가지로 여기에 함수 호출 내역이 있습니다. 로그를 보면 get-schemas, get-tables, 유틸리티 함수, 그리고 open table 함수가 호출된 것을 확인할 수 있습니다.
이렇게 다양한 유형을 만들기 위해 많은 노력을 기울이셨는데, 이제 다른 사람들과 공유하고 싶으시군요. 마지막으로 이야기할 주제는 바로 그 공유 방법입니다. 제가 또 다른 체크리스트를 준비했습니다.
직접 작성한 파이썬 코드가 있을 수 있지만, 작성 방식에 따라 패키지 형태로 구조화하는 것이 좋을 수 있습니다. 패키지 구조화의 목적은 모든 코드를 한데 모아 pip 또는 이 경우에는 JMP로 래핑된 jpip과 같은 도구를 사용하여 설치할 수 있도록 하는 것입니다. 또한 설치 시 필요한 패키지의 의존성을 지정할 수 있습니다. 예를 들어, S3의 경우 PyPI에 있는 Boto3 패키지에 의존하는데, 패키지를 사용하면 이러한 의존성을 매우 자연스럽게 지정할 수 있습니다.
기본 구성을 생성해야 합니다. 앞서 데이터 커넥터 편집기에서 유형 이름을 직접 입력했던 것을 기억하시나요? 물론 그렇게 하는 것도 괜찮지만, 구성 목록에서 원하는 것을 찾아서 새 구성을 만들 수 있다면 훨씬 편리할 것입니다. 전체 이름을 기억할 필요 없이 목록에서 원하는 것을 찾아 새 구성을 만들 수 있으니까요.
아마 설치 스크립트를 작성해야 할 겁니다. 아주 훌륭한 파이썬 패키지가 있는데, 실제로 사용할 수 있는 위치에 설치해야 하거든요. 자동으로 설치할 수 있다면 정말 좋을 것 같습니다.
마지막으로, 이 모든 것을 애드인 형태로 만들고 싶습니다. 애드인을 사용하면 설치가 간편하고, 마켓플레이스를 통해 배포할 수 있습니다. 어쨌든, 이 모든 것이 하나의 패키지 파일에 담겨 있습니다.
자, 어떤 모습인지 살펴볼까요? 여기 오늘 오전에 살펴봤던 코드의 더욱 발전된 버전이 포함된 추가 기능이 있습니다. 압축을 풀어서 안에 무엇이 있는지 보여드리겠습니다. 목록의 첫 번째 항목은 파이썬 패키지였던 것 같습니다. 제가 여기에 만들어 놓았습니다. 파이썬 코드가 있는데, 파이썬 프로젝트… 아니, 파이썬 패키지로 구성되어 있습니다. pyproject.toml 파일도 있습니다. 오늘 이 파일을 어떻게 만드는지 자세히 설명드릴 시간은 없지만, 온라인에서 관련 자료를 찾아보실 수 있습니다.
데이터 커넥터 폴더가 있습니다. 이 폴더에는 애드온과 관련된 구성 파일, 즉 기본 구성 파일이 저장됩니다. 예를 들어, 이 파일 중 하나를 살펴보면 유형을 지정하는 한 줄만 있는 것을 볼 수 있습니다. 추가 구성은 지정하지 않지만 사용자가 지정할 수 있는 기준점을 제공합니다. 그리고 이 경우에는 addinLoad라는 폴더가 있는데, 여기에 설치 스크립트가 포함됩니다.
물론 이 모든 것을 직접 만들 수도 있지만, JMP의 추가 기능 생성기를 사용할 수도 있습니다. 파일, 새로 만들기, 추가 기능을 선택하면 이름을 지정하고 ID를 입력할 수 있습니다. 최소 JMP 버전도 지정할 수 있는데, 이 경우에는 19가 적합합니다. 시작 스크립트에는 패키지를 설치하는 스크립트를 입력합니다. 패키지는 한 번만 설치되도록 해야 합니다.
이제 추가할 파일들이 준비되었습니다. 이 경우에는 이미 압축이 풀린 상태로 여기에 있지만, 처음 직접 만드는 경우라면 다른 위치에 있을 수도 있습니다. 패키지를 추가해 보겠습니다. 보시다시피 필요한 모든 파일이 있습니다. 데이터 커넥터도 추가할 수 있습니다. 서브스크립트가 있으면 이제 저장하고 나만의 애드인을 만들 수 있습니다. 모든 준비가 끝나면 애드인 생성 과정은 매우 간단할 것입니다.
제가 보여드리고 싶었던 건 이게 전부입니다. 정리해 보겠습니다. 우선, 왜 통합이 필요한지에 대해 이야기하고 싶습니다. 제가 서두에서 말씀드렸듯이, 데이터 커넥터 프레임워크는 구성 편집, 공유, 쿼리 빌더를 사용한 대화형 쿼리 구성 등 다양한 기능을 제공합니다. 따라서 데이터 소스를 래핑하는 것이 타당한 이유가 됩니다. 바로 이 부분이 핵심입니다. JMP에서는 모든 것이 데이터 테이블처럼 보이지만, 우리는 이를 데이터베이스처럼 보이게 만들고 싶어합니다.
어떤 코드를 작성해야 할까요? 정의해야 할 다양한 서브클래스, 작성해야 할 여러 함수, 옵션을 지정하는 방법 등을 살펴보았습니다. 마지막으로, 애드인을 만들고 작성한 코드를 다른 사람과 공유하거나 JMP 마켓플레이스에 등록하는 방법에 대해서도 이야기했습니다.
어떻게 보면 이것은 가능한 모든 것에 대한 비교적 간략한 개요입니다. 어떤 분들은 꼼꼼하게 메모를 하거나 스크린샷이나 사진을 많이 찍어두시겠지만, 저처럼 나중에 참고할 만한 자료가 더 필요할 수도 있습니다. 다행히 필요한 정보는 모두 준비되어 있으며, 앞으로도 계속 추가할 예정입니다.
오늘 보여드린 API는 현재 문서화되어 있습니다. EA 노트의 데이터 액세스 섹션에서 확인하실 수 있습니다. 최신 버전을 사용하고 있는지 확인하시는 것이 좋습니다. 변경 사항이 없는 경우, 최신 버전이 현재 EA 버전이 아닐 수도 있습니다. 스크립팅 인덱스에 관련 문서를 추가할 예정입니다. EA 노트처럼 전체적인 개요를 제공하지는 않지만, API의 개별 기능에 대한 참조 자료로 활용될 수 있을 것입니다.
마지막으로, 아까 보여드렸던 애드인은 좀 더 개발 중이며, JMP 마켓플레이스에 출시할 예정입니다. 이 애드인이 API를 보여주는 것은 물론, 파이썬 패키지를 만들고 애드인으로 게시하는 방법까지 알려주는 유용한 자료가 되기를 바랍니다.
이 모든 문서를 바탕으로, 오늘 보셨던 모든 내용을 다시 한번 보여드리고, 시간이 부족해서 설명드리지 못했지만 유용할 수 있는 몇 가지 고급 기능도 추가로 보여드리겠습니다. 꼭 확인해 보세요.
마지막으로, 향후 계획에 대해 말씀드리겠습니다. JMP 20 이상 버전에서는 이 API에 대한 추가 확장 기능을 고려하고 있습니다. 예를 들어, 데이터를 처리하기 위해 JMP가 전체 데이터 테이블을 로컬로 가져오는 것을 보셨을 수도 있습니다. 이는 open table 함수에서 반환해야 하는 데이터 테이블 전체이기 때문입니다. 그런 다음 앞서 언급했듯이 SQLite를 통해 로컬에서 해당 데이터를 사용합니다.
하지만 만약 서버 측에서 일부 처리를 할 수 있고, 모든 파일을 로컬에 다운로드할 필요가 없다면, 저희는 그러한 방식을 지원하고 싶습니다. 그러한 기능을 제공할 수 있는 방법을 검토해 볼 예정입니다.
이것으로 마무리하겠습니다. 들어주셔서 감사합니다. 오늘 배운 내용을 바탕으로 이 데이터 커넥터 프레임워크에 포함된 새로운 데이터 소스를 만들고, 이를 활용하여 애드인을 게시하고, 궁극적으로 데이터를 더 쉽고 효율적으로 다루고 JMP에 가져올 수 있기를 바랍니다. 다시 한번 감사드립니다. 이상입니다.