Pesquisar

質問
· 2024年7月24日

Import /export Web application

Hi Guys,

 

Is there a way to import /export Web Applications? I can see that those web application that I created are also showing in Studio under CSP Files folder and I tried right clicking on some on the folders that seems to be representing my web application then export but didn't work.

 

Thanks

3 Comments
ディスカッション (3)3
続けるにはログインするか新規登録を行ってください
お知らせ
· 2024年7月24日

VSCode extension for IPM (InterSystems Package Manager) Now Available

Overview

The extension and source code are now available

After having some discussions at Global Summit and using a lot of package managers in my day to day development (npm,nuget,Chocolatey, etc) in addition to recently using the InterSystems Package Manager for some CICD process I'm building using Intersystems IRIS and IRIS 4 Health, I wanted an easy and integrated way to search/view/install packages related to the Intersystems tech stack.

I recently built a VSCode extension for IPM repositories that I will be open sourcing and publishing to the marketplace but wanted create this post to get some feedback from the community.

Download Information

You can download the extension within VSCode or at https://marketplace.visualstudio.com/items?itemName=extensionsbyjohn.ipm.... Just search for ipm.explorer


Github respository

Click here for the github repository

Video

Initial Screen

Some features in the extension:

  • VSCode setting for defining multiple repositories
  • Activity Bar Icon/Explorer View
  • List of packages in custom view
  • List/Open github repository configured in package
  • Details for package in a custom view
  • Copy ZPM install command for use in IRIS terminal

Setup/Settings:

When you first start the extension, you will need to configure it. You can do this by accessing the settings.json file and adding something like the following.

"ipm.repositories": [
        {
            "name":"Public IPM",
            "url":"https://pm.community.intersystems.com"
        },
        {
            "name":"Internal Packages",
            "url":"https://[insert private repo here]"
        },
        {
            "name":"Test Packages",
            "url":"https://[insert private repo here]"
        }
    ]

Screenshots:

Ideas/Future

After building this and working with the API, I'd like to propose a couple updates that potentially could be added to the manifest/API for packages to make integrations like this a little easier

  • License field: (This will let the users know if the package license is compatable with their usage)
  • Logo: encoded image for the package. Allow the developer of the package to specify an image
  • Readme: Allow the developer of the package to include a readme markdown file in the package. This can then be displayed in the details section of the extension.
  • Author: Include the author of the package (can be displayed the details view)
  • Verified: Allow for an author to be verified. For example Intersystems could be a verified author

Open Source:

Click here for the github repository

Comments/Suggestions

Let me know what you think or if you have suggestions let me know. Would you be interested in using this?

3 Comments
ディスカッション (3)2
続けるにはログインするか新規登録を行ってください
記事
· 2024年7月23日 6m read

FHIR 实践

FHIR是标准,是规范,使用FHIR使大家可以使用同一种语言、语义进行交流,名称、API都是统一的,只要符合FHIR标准,任何系统都可交互。对业务开发者来说,大部分接口交互的定义交给FHIR来处理,效率大大提高。

学习FHIR首先是一个再学习的过程,这个过程对有业务开发基础的人员来说要有个入门,这个入门就是FHIR的各个结构定义的含义,以及与业务系统数据以及接口的对照关系。

FHIR需要用到的几个工具:

 

InterSystems IRIS对于 FHIR相关内容的开发,带来了极大的便利性,里面自带一套定义好的FHIR服务器,也就是包含了FHIR定义的资源及其操作方法。

我这里选用的是最新版本的InterSystems IRIS 2024,做了传统业务系统中科室、医院、病人信息、就诊信息的FHIR转换,主要过程如下:

1. 安装InterSystems IRIS

2. 配置FHIR 服务器

3. 在HIS数据库(IRIS2022)上写一个Restful API 接口,做为对外的统一出口

// w ##class(src.rest.inif).HttpOut({})
ClassMethod HttpOut(Para As %Library.DynamicObject, Type = "1") As %Library.DynamicObject
{
  new (Para,Type)
  s valueType=$classname(Para)
  if (valueType="%Library.DynamicArray"){s Param=[]}
  if (valueType="%Library.DynamicObject"){s Param={}}
  s iter=Para.%GetIterator()
  while iter.%GetNext(.key , .srcKey ) {
    d Param.%Set(key,srcKey)
  }
  s retObj={}
  if ($classname(Param)="%Library.DynamicObject") {
    return:(Param.%Size()=0) {}
  }else {
    s Param=##class(%Library.DynamicObject).%FromJSON(Para)
  }
  set httpReq=##class(%Net.HttpRequest).%New()
  set httpReq.HTTPVersion="1.1"
  set httpReq.Timeout=5
  set httpReq.SocketTimeout=10
  if (Param.Port="443") {s httpReq.Https=1
    s httpReq.SSLConfiguration="ISC.FeatureTracker.SSL.Config"
  } else {s httpReq.Port=Param.Port}
  ;b ;http1                                                                                                                                                                                           
  s httpReq.Server=Param.Server
  
  //表头
  if ((Param.%IsDefined("Header"))&&(Param.Header.%Size()>0)){
      set iter = Param.Header.%GetIterator()
      while iter.%GetNext(.key , .value ) {
        do httpReq.SetHeader(key,value)
     }
  }
  //参数
  if ((Param.%IsDefined("Param"))&&(Param.Param.%Size()>0)){
      set iter = Param.Param.%GetIterator()
      while iter.%GetNext(.key , .value ) {
        do httpReq.SetParam(key,value)
     }
  }
  if ($classname(Param.EntityBody)="%Library.DynamicObject") {
    do httpReq.EntityBody.Write((Param.EntityBody).%ToJSON())   
  }

  ;b ;http2
  if '(Param.%IsDefined("type")) {s Param.type="Post"}
  if (Param.type="Get") {
    set sc=httpReq.Get(Param.Url)
    ;b ;httpget
  }
  if (Param.type="Post") {
    set sc=httpReq.Post(Param.Url,0)
  }
  if (Param.type="Put") {
    ;w "put"_Param.Url,!
    set sc=httpReq.Put(Param.Url)
  }
  if (Param.type="Patch") {
    
    set sc=httpReq.Patch(Param.Url)
  }
  if (Param.type="Delete") {
    set sc=httpReq.Delete(Param.Url)
  }
  
   
  ;B ;httpsc
  if sc=1 { 
    if Type="1" {
      set retObj=httpReq.HttpResponse.Data.Read()
      if $classname(retObj)="%Library.DynamicObject" {
        set retObj=##class(%DynamicObject).%FromJSON(retObj)
      }else{
        return retObj
      }
    }
    if Type="2" {
      ;b ;aa2
      set retObj=httpReq.HttpResponse.Data.Read()
    }
    if Type="3" {set retObj=httpReq.HttpResponse
      ;B ;3
    }
  }else {q "0:网络不通"}
  ;b ;comhttp
  ;set retObj=$zconvert(retObj,"I","UTF8")
  s httpReq=""
  b:retObj="Service Unavailable"
  q retObj
}

4. 做一个对象与FHIR转换程序。(目的是以后将HIS里面的数据转换为FHIR

5. 整理FHIRJSON对象:通过Forge或是网站https://hl7.org/FHIR/R4B/resourcelist.html,把FHIR 定义的资源中的各个数据元素内容转换为对象的定义。在整理的过程中我们总结了下面四点要注意的地方:

  1. FHIR规范里有部分内容是多级的,而我们的业务一般都是平级,如病人信息里的地址(address)
  2. FHIR 规范里定义的valueSetcodesystem,就是对应我们日常理解的代码表。
  3. 对于业务内容的部分,我们先整理医院、科室信息,再整理病人信息、就诊信息。
  4. 对于我们现有业务系统的主键或是关联外键值,在FHIR里面可以放在identifier面,做为查询的条件或指向

6. 从HIS业务库里把职业、医院等代码表数据组成JSON对象,与FHIRJSON对象做对照并上传FHIR服务器

7. 再把病人信息和就诊信息从HIS业务库取出数据组成JSON对,与FHIRJSON对象做对照并上传FHIR服务器

 

下面是一个地址(address)字段组成的json格式例子。

"telecom": [
       {"system": "other","value": "PAPMIMobPhone"}],
    "address": [
      {
        "use": "home",
        "type": "both",
        "line": ["aaaa"],
        "state":"PAPMICTProvinceDR",
        "city": "PAPMICityAreaDR",
        "district": "Rainbow",
        "state": "PAPMICTProvinceDR",
        "postalCode": "3999",
        "period": {
          "start": "1974-12-25"
        }
        
      },

 

在这里面以FHIR对象为基准,HIS对象名放在值里面。用一个统一的方法把HIS里的对象转换成FHIR 格式 JSON对象。转换完后上传到FHIR服务器:

  while iter.%GetNext(.key , .value ) {
    s ret=##class(src.comm.comm).objToObj(value,target)
    ;if (value.CTLOCStartTime<value.CTLOCEndTime){set ret.status="inactive"}else{set ret.status="active"}
    s conObj={"resource":"Patient","EntityBody":(ret),"Param":{"identifier":(value.PAPMINo)}}
    s tmpObj=##class(src.comm.comm).operateDataFhir(conObj)
    if (tmpObj.code=1){
      s ret=##class(%DynamicObject).%FromJSON(tmpObj.data)
      d retArr.%Push(ret)
    }
    ;d retArr.%Push(value)
  }
  
  
  

 

转换示例

// 根据对照做对象转换
// s ret=##class(src.comm.comm).objToObj(src,target)
ClassMethod objToObj(src, target) [ Language = objectscript ]
{
  
  
  n (src, target)
  ;s retObj=target
  s iter=target.%GetIterator()
  s valueType=$classname(target)
  if (valueType="%Library.DynamicArray"){s retObj=##class(%Library.DynamicArray).%New()}
  if (valueType="%Library.DynamicObject"){s retObj=##class(%Library.DynamicObject).%New()}
  while iter.%GetNext(.key , .srcKey ) {
    if ($classname(retObj)="%Library.DynamicArray"){d retObj.%Push(srcKey)}
    if ($classname(retObj)="%Library.DynamicObject"){d retObj.%Set(key,srcKey)}
    
    s valueType=$classname(srcKey)
    if ((valueType="%Library.DynamicArray")||(valueType="%Library.DynamicObject")){
      s temp=##class(src.comm.comm).objToObj(src,retObj.%Get(key))
      d retObj.%Set(key,temp)
    }else{
      //为字符时
      IF ($l(srcKey,"---")>1){
        s srcKey=$replace(srcKey,"---","")
        if (src.%IsDefined(srcKey)){
          if (src.%Get(srcKey)=""){d retObj.%Remove(key)}
          else{d retObj.%Set(key,src.%Get(srcKey))}
        }else{
          d retObj.%Remove(key)
        }
      }else{
        if (src.%IsDefined(srcKey)){
          if (src.%Get(srcKey)=""){d retObj.%Set(key,"空")}
          else{ d retObj.%Set(key,src.%Get(srcKey))}
        }
     }
    }
  }
  return retObj
}

 

进行查询

 

可以看到查出了两个符合查询条件的病人。

1 Comment
ディスカッション (1)1
続けるにはログインするか新規登録を行ってください
質問
· 2024年7月23日

Getting service account token for Online Demo GKE workflow

I'm trying to leverage the workflow from this repo so I can create an online demo for my project: https://github.com/intersystems-community/iris-google-run-deploy-template.

I saw that we need to ask for the service account token because I mistakenly tried to obtain my own and obviously was getting permission errors.

So how should I go about getting the token? Thanks!

ディスカッション (0)2
続けるにはログインするか新規登録を行ってください
記事
· 2024年7月23日 4m read

リンクテーブルと外部テーブルについて

これは InterSystems FAQ サイトの記事です。
 

JDBC および ODBC 経由でInterSystemsIRISから外部データベースにアクセスしたい場合、SQLゲートウェイを使用しリンクテーブルを作成して接続できます。

2023.1以降のバージョンでは、リンクテーブルに加えて、外部テーブル/FOREIGN TABLE を使用することが可能となりました(2024.1時点で実験的機能)。

外部テーブルというのは、物理的に別の場所に保存されているデータを IRIS SQL に投影する非常に便利な機能です。

外部テーブルを使用する場合は、Java(2023.1の場合は1.8~)を事前にインストールし、JAVA_HOME環境変数を設定するだけで、簡単に接続することが可能です。

※JAVA_HOME環境変数設定例:
 


外部テーブルの使用方法については、以下の記事で紹介しております。
レシピデータセットを外部テーブルで読み込み、組み込みPythonでLLMを使って分析する (Langchain + OpenAI)
 


こちらの記事では、外部テーブルで作成できる2種類のテーブル(「CSVファイル直接接続」と「外部DBへのJDBCゲートウェイ経由での接続」)の簡単なサンプル作成例と、外部テーブルの特徴を紹介しています。
 

1-1. 簡単なサンプル作成例(CSVファイル編:ファイルから外部テーブル作成)


a. 外部データラッパとする CSVファイルを用意します(例:C:\temp\FT\managers.csv)

 ※サンプルCSV(managers.csv)

ID,Name,Title,HireDate,CompanyCar
111,"Cornish,Irving",Senior Support Manager,1992-02-10,6
222,"Aquino,Aric","Manager, Technical Account Management",1992-07-15,3
333,"Masterson,Arthur","Director, Customer Support",2002-10-01,9
444,"Deyn,Ernest",Director Customer Support,2000-08-15,4
555,"Lee,Eileen","Manager, Product Support",2002-06-17,3
666,"Knapp,Ashtyn",Senior Support Manager,2002-10-01,11
777,"King,Michael",Senior Support Manager,2003-04-10,2


b. 外部サーバ(WRC.Files)を作成します

CREATE FOREIGN SERVER WRC.Files FOREIGN DATA WRAPPER CSV HOST 'C:\temp\FT\'


c. 外部テーブルを作成します

CREATE FOREIGN TABLE WRC.Managers (
  ID INTEGER, 
  Name VARCHAR, 
  Title VARCHAR, 
  HireDate DATE
) SERVER WRC.Files FILE 'managers.csv' USING
{ "from" : {
       "file" : {
          "header": 1
       }
   }
}


1-2. 簡単なサンプル作成例(JDBCゲートウェイ接続経由編)


a. 外部DBへの JDBCゲートウェイ接続を作成します
 管理ポータル:
 [システム管理] > [構成] > [接続性] > [SQLゲートウェイ接続] 新規作成:WRC


b. 接続用の外部サービス(例:WRC.Data)を作成します。  

CREATE FOREIGN SERVER WRC.Data FOREIGN DATA WRAPPER JDBC CONNECTION 'WRC'


c. 外部サーバ内の任意のテーブルに対して外部テーブルを作成します。
  ※外部テーブルは CREATE FOREIGN TABLE コマンドで定義する必要があります。
   クラス定義を作成して外部テーブルを作成することはできません。

CREATE FOREIGN TABLE Remote.Problems SERVER WRC.Data TABLE 'SQLUser.Problem'


d. 作成後、クエリを実行します。

SELECT ProblemOwner, OpenDate FROM Remote.Problems WHERE OpenDate = '2023-03-09'

外部言語サーバ(%Java Server)が起動されていない状態でクエリを実行すると、以下のようなエラーが返ります。

SQLCODE: <-230>:<Foreign table query Execute() failed>]
  [%msg: <Foreign Tables - ERROR #5023: Remote Gateway Error: Connection cannot be established>]


2. 外部テーブルの特徴

・外部テーブルとのJoinが可能

・ローカルテーブルとのJoinが可能

・外部テーブル用に作成されるクラスは非表示となる(SQLテーブルとしては表示可能)

・削除する場合は、DROP FOREIGN TABLE コマンドで行う(%MANAGE_FOREIGN_SERVER 管理特権が必要)
 例:DROP FOREIGN TABLE WRC.Advisor

・外部テーブルに対してクエリを実行すると、クエリごとにすべてのフィールドが取得される

・ストリーム(Stream)フィールドの取得方法は、リンクテーブルと同様に substring 関数 を使用可能

例:

select substring(clob1,1,50) from linked.newclass1


※うまく動作しない場合は、%Java Server が問題なく起動できているかご確認ください。
 [システム管理] > [構成] > [接続性] >[外部言語サーバ]  
 %Java Server が Start されているか

 

外部テーブルの詳細については、以下のドキュメントをご覧ください。
外部テーブル


※SQLゲートウェイ/リンクテーブルの使用方法については、以下のような記事をご紹介しております。

(管理ポータルで行う)リンクテーブルをプログラムで行う方法
SQL ゲートウェイを使用した外部データベースへのアクセス方法について
プログラムでSQLゲートウェイ接続設定を作成する方法

ディスカッション (0)0
続けるにはログインするか新規登録を行ってください