#VSCode

0 关注者 · 24 帖子

VSCode 是 Microsoft 热门跨平台编辑器 VisualStudio Code 的缩写形式。

了解更多信息

文章 Jeff Liu · 十一月 6, 2025 4m read

动机

直到开始新工作,我才了解到ObjectScript。实际上,Objectscript并不是一种年轻的编程语言。与 C++、Java 和 Python 相比,它的社区并不活跃,但我们很想让这里更有活力,不是吗?

我注意到,有些同事在理解大型项目中的类关系时感到棘手。目前还没有易于使用的现代化类图工具适用于ObjectScript。

相关工作

我尝试过相关的工作:

——InterSystems 类视图:
1. https://github.com/intersystems-community/ClassExplorer
这个工具很棒,类图显示清晰美观。但存在Docker构建问题:“#0 0.512 exec ./irissession.sh: no such file or directory”。我猜这是为Studio设计的支持功能,而非VSCode。它似乎需要手动导入项目,且需要一定配置才能使用。

2. https://github.com/gjsjohnmurray/vscode-objectscript-class-view
这是另一个给我带来灵感的伟大作品。类结构清晰,不仅支持项目中的类,也支持库中的类。但看起来像是VSCode大纲的增强版。

——其他语言的 VSCode 类图表视图插件

0
0 11
文章 Nicky Zhu · 十月 31, 2025 20m read

目录

  1. 本文目的
  2. 什么是容器,它们为什么对 IRIS 有意义
     2.1 容器和镜像简介
     2.2 为什么容器对开发者很有用
     2.3 为什么 IRIS 可以很好地与 Docker 配合使用
  3. 先决条件
  4. 安装 InterSystems IRIS 镜像
     4.1 使用 Docker Hub
     4.2 拉取镜像
  5. 运行 InterSystems IRIS 镜像
     5.1 启动 IRIS 容器
     5.2 检查容器状态
     5.3 在容器终端执行代码
     5.4 访问 IRIS 管理门户
     5.5 将容器连接到 VS Code
     5.6 停止或移除容器
     5.7 使用绑定挂载设置特定密码
     5.8 使用持久化 %SYS 卷
      5.8.1 可以使用持久化 %SYS 存储什么
      5.8.2 如何启用持久化 %SYS
  6. 使用 Docker Compose
     6.1 Docker Compose 示例
     6.2 运行 Docker Compose
  7. 使用 Dockerfile 运行自定义源代码
     7.1 Dockerfile 示例
     7.2 Docker Compose 示例
     7.3 了解层、镜像标记和构建与 运行时
     7.4 源代码和初始化脚本
     7.5 使用 Dockerfile 构建镜像
     7.6 在容器化 IRIS 终端中运行指令
  8. 结语和未来计划


1. 本文目的

InterSystems 开发者社区已经有很多优秀的文章解释了 Docker 是什么、最重要的命令以及 InterSystems IRIS 在容器化环境中的多个用例。

本系列文章的目的略有不同。 由于我非常喜欢分步指南,我想创建一份全面的讲解,介绍如何在 InterSystems IRIS 中配置和使用 Docker,我们先从最基础的场景开始,逐步过渡到更高级的场景,例如多命名空间实例、互连容器、与外部系统的集成以及用于了解 UI 的应用程序。

2. 什么是容器,它们为什么对 IRIS 有意义

2.1 容器和镜像简介

按照传统方法,要想运行应用程序,需要将版本与您的操作系统进行匹配,并针对特定目标对其进行打包。 同时,每个应用程序都应当打包,以便专门与某个目标系统配合使用。 如果您希望应用程序在 macOS 和 Windows 上运行,必须更改应用程序设计并针对不同的系统进行打包。Docker 镜像和容器是应用程序部署技术,通过让开发者将软件打包一次并在任何地方运行来解决此问题。

Docker 是一个将软件打包到容器中的软件平台。 Docker 镜像(或容器镜像)是独立的可执行文件,包含创建和运行容器的所有指令(库、依赖项和文件)。 Docker 镜像可共享、可移植,因此您可以一次在多个位置部署同一个镜像。Docker 容器是一个运行时环境,具有运行应用程序代码所需的所有必要组件,无需使用主机依赖项。  

与虚拟机不同,容器是轻量级的。 它们不需要完整的操作系统,只使用特定应用程序所需的二进制文件和库,通过 Docker 引擎直接在主机操作系统上运行,这使其更加高效。 多个隔离的容器可以在同一台计算机上并行启动,互不干扰。

2.2 为什么容器对开发者很有用

  • 隔离:在清晰、可重现的环境中运行,不会影响您的主机系统。
  • 可重现性:确保您的设置在不同的计算机上以相同的方式工作。
  • 轻松设置:使用一个命令,只需几秒钟即可启动 IRIS 实例,无需手动安装。

2.3 为什么 IRIS 可以很好地与 Docker 配合使用

在 Docker 中运行 InterSystems IRIS 有几项优势:

  • 应用程序运行并且可以在隔离的容器中进行测试
  • 可以使用共享版本控制系统(如 Git),无需直接在服务器上操作
  • 容器化环境可以在任何阶段重现,从而在整个软件生命周期中保持一致性。
  • 您的应用程序可以轻松地在每台计算机上运行。

3. 先决条件

要在 Docker 容器中运行 InterSystems IRIS,您必须具有:

4. 安装 InterSystems IRIS 镜像

4.1 使用 Docker Hub

Docker Hub 是 Docker 镜像的中心注册表。 它提供了一个庞大的预构建镜像库,您可以将其作为切入点。 InterSystems 在其中发布官方 IRIS 社区版镜像,您可以下载该镜像以在自己的容器中本地运行 IRIS。 您还可以使用 Docker Hub 推送自己的自定义镜像,以便在团队中共享或分发给社区。Docker Hub 既可以在线使用,也可以嵌入到 Docker Desktop 中。

4.2 拉取镜像

一些常见的 Docker 镜像命令包括:

命令描述
docker pull <image>从 Docker Hub 下载镜像
docker images列出所有本地镜像
docker rmi <image>移除一个或多个镜像

您可以直接在镜像的 Docker Hub 页面上找到确切的拉取命令:

对于 InterSystems IRIS 镜像,该命令为:

docker pull intersystems/iris-community:latest-cd

或者,您可以在 Docker Desktop 搜索栏中搜索 iris-community 并点击 Pull

安装后,您应当拥有在本地镜像中列出的 InterSystems IRIS 镜像:

5. 运行 InterSystems IRIS 镜像

从 Docker Hub 中拉取出 InterSystems IRIS 镜像后,您可以在容器内运行该镜像。

以下是常用的 Docker 容器命令

命令描述
docker run -d <image>以分离模式运行:在后台启动容器并立即将控制权返还给终端。
docker run -p <host>:<container> <img>将主机端口映射到容器端口
docker ps列出正在运行的容器
docker ps -a列出所有容器(包括已停止的容器)
docker exec -it <container> bash在正在运行的容器中执行命令
docker logs <container>查看容器日志
docker stop <container>停止正在运行的容器
docker start <container>启动已停止的容器
docker restart <container>重启容器
docker rm <container>移除容器

5.1 启动 IRIS 容器

您可以通过 Docker Desktop UI 启动名为“my-iris”的 InterSystems IRIS 社区版容器,只需在 Images 面板中点击要运行的镜像的 Run 按钮即可。 对于 InterSystems 镜像,可以指定一些可选的设置,例如在主机上公开哪些端口来与容器内运行的服务进行通信。

可以通过上面显示的菜单完成操作,具体如下:

  • 左侧 → 主机上的端口
  • 右侧 → 容器内的端口

常用 IRIS 端口(容器内)

  • 1972 → 超级服务器端口:由 IRIS 用于网络协议(ObjectScript、JDBC 等)。
  • 52773 → Web 服务器端口:由 IRIS 用于管理门户(Web 界面)。

如果没有显式映射端口,Docker 将在主机上指定随机端口。

或者,可以使用终端来运行容器:

docker run --name my-iris -d --publish 9091:1972 --publish 9092:52773 intersystems/iris-community:latest-cd

在本例中:

  • 主机上的 9091 映射到容器内的 1972(超级服务器)。
  • 主机上的 9092 映射到容器内的 52773(管理门户)。

5.2 检查容器状态

运行此命令后,运行 docker ps 以验证容器是否正常运行。

> docker ps
CONTAINER ID   IMAGE                                   COMMAND                 CREATED         STATUS                            PORTS                                                                                        NAMES
907d4c2b4ab5   intersystems/iris-community:latest-cd   "/tini -- /iris-main"   3 seconds ago   Up 2 seconds (health: starting)   0.0.0.0:9091->1972/tcp, [::]:9091->1972/tcp, 0.0.0.0:9092->52773/tcp, [::]:9092->52773/tcp   my-iris

正在运行的容器也会列在 Docker Desktop Containers 面板中:

相关镜像的状态将是 In Use,如 Images 面板中所示:

5.3 在容器终端执行代码

当容器状态显示 Running 时,表示一切正常。 

您可以进行测试,只需打开容器终端(点击 Docker Desktop 的 Containers 面板内的容器名称并转到 Exec)并输入以下内容即可:

iris session IRIS

这将在 Docker 容器中打开一个 IRIS 终端,您可以在其中使用标准的 ObjectScript 语法来执行命令和脚本。

5.4 访问容器化实例的 IRIS 管理门户

接下来,打开浏览器并导航到:

http://localhost:9092/csp/sys/UtilHome.csp

默认情况下,IRIS 容器使用用户 _SYSTEM 和密码 SYS。登录后需要更改密码。

这将为您提供 IRIS 管理门户的完整访问权限,这样您可以直接从 Web 界面管理命名空间、数据库和其他 IRIS 功能。

5.5 将容器连接到 VSCode IDE

您可以使用映射的超级服务器端口(默认为容器内的 1972,例如主机上的 9091)和 Web 服务器端口(默认为容器内的 52773,例如主机上的 9092)将您喜欢的 IDE(例如 VS Code 或 Studio)连接到 IRIS 容器。 这样您可以直接针对正在运行的容器开发和测试 ObjectScript 代码。

将容器连接到 VSCode:

  • 安装 InterSystems ObjectScript 扩展程序包
  • 打开 InterSystems Server 扩展程序
  • 点击三个点和“Edit server”
  •  
  • 点击“Edit in settings.json”
  • 将此元素添加到“intersystems.servers”json:
"docker_iris": {
    "webServer": {
        "scheme": "http",
        "host": "localhost",
        "port": 9092
    },
    "description": "Connection to Docker container."
}
  • 服务器现已连接。 您可以使用 _SYSTEM 用户登录。
  • 您可以看到,USER 是唯一可用的命名空间:

5.6 停止或移除容器

要停止正在运行的容器,请使用以下命令:

docker stop my-iris

再次启动容器

要再次启动容器,请使用以下命令:

docker start my-iris

移除(删除)容器

要移除容器实例,但移除镜像,请使用:

docker rm my-iris

除非您挂载了卷,否则容器内的所有数据都将丢失(我们将在后续段落中讨论这个问题)。

5.7 使用绑定挂载设置特定密码

在启动容器时,可以使用密码文件设置自定义密码。 该文件将保存在我们的主机上,并使用绑定挂载机制复制到容器中。

当您使用绑定挂载时,主机上的文件或目录将从主机挂载到容器中,从而允许在 Docker 主机上的开发环境和容器之间共享源代码或构建工件。

  • 创建名为 password.txt 的文件,其中仅包含字符串形式的密码(注意! 记下密码,以后会用到)。
  • 复制其路径,本例中为 C:\InterSystems\DockerTest\password\password.txt
  • 运行以下命令:
docker run --name my-iris -d --publish 9091:1972 --publish 9092:52773 --volume "C:\InterSystems\DockerTest:/durable" intersystems/iris-community:latest-cd --password-file /durable/password/password.txt 

容器运行后,可以使用用户 _SYSTEM  和您在密码文件中写下的密码登录。

在 Docker 容器内,您会看到一个 password.txt.done 文件。您的主机文件夹中会有一个相同的文件。

文件扩展名会更改为 .done,以避免密码以纯文本形式保留。 这是 InterSystems IRIS 中对密码文件的标准操作。 因此,在从 password.txt 文件读取密码并将默认 IRIS 用户 (_SYSTEM) 更新为该密码后,出于安全原因,该文件会附加 .done 并移除密码。

您可以使用自定义密码登录管理门户(我告诉过您记下来 :D)。 登录后,InterSystems IRIS 不会强迫您更改密码。

请注意,如果在没有挂载任何持久化卷的情况下移除了容器,然后重启(有关详情,请参阅下一段),则不会再次从 password.txt 文件中读取密码,因为它已被替换为 password.txt.done。 如果是这种情况,将使用标准的“SYS”密码。 

5.8 使用特定的持久化卷启动容器

默认情况下,当您使用 docker rm <container's name> 命令移除正在运行的 Docker 容器时,保存在该容器内的任何内容都将消失。

为了避免丢失数据,InterSystems IRIS 提供了持久化 %SYS 功能。 这可以让实例将所有重要的文件都存储在您的主机上,以便在容器和实例重启后它们仍然存在。

5.8.1 可以使用持久化 %SYS 存储什么?

一些示例包括:

  • 配置文件(iris.cpfhttpd.conf
  • Web 网关配置和日志 (/csp)
  • 系统数据库(IRISUSERIRISSECURITYIRISTEMP 等)
  • 日志、写入镜像文件 (WIJ) 和临时文件
  • 日志文件(messages.logSystemMonitor.log 等)
  • 许可证密钥 (iris.key)
  • 您创建的任何其他数据库

5.8.2 如何启用持久化 %SYS

首先,从主机中选择一个文件夹,如 C:\InterSystems\DockerTest

  • 在 Linux 上,创建 irisowner 用户并为其授予目录所有权,确保 IRIS 可以写入该文件夹:
adduser irisowner
chown -R irisowner:irisowner /InterSystems/DockerTest
  • 在 Windows 上,您可以跳过这一段,因为 Docker Desktop 将使用您当前的 Windows 用户权限挂载该文件夹。

然后,挂载您的主机文件夹并使用 ISC_DATA_DIRECTORY 变量告知 IRIS 将其持久化数据写入何处:

  --volume "C:\InterSystems\DockerTest:/durable" --env ISC_DATA_DIRECTORY=/durable/iris

在终端上运行的完整指令是:

docker run --name my-iris -d --publish 9091:1972 --publish 9092:52773 --volume "C:\InterSystems\DockerTest:/durable" --env ISC_DATA_DIRECTORY=/durable/iris intersystems/iris-community:latest-cd --password-file /durable/password/password.txt

此时,您可以检查您的容器,看到一个持久化文件夹已装载并包含目录 iris/(对于持久化 %SYS)和 password/。 在主机上,您也可以看到以下两个目录:

如果容器停止并被移除,当您使用相同的 Docker Compose 命令重新创建容器时,IRIS 将使用 iris/ 文件夹中的数据恢复其先前的状态(用户、配置、日志、数据库等),因此不会丢失任何内容。 您可以通过创建 Web 应用程序、停止并移除容器,然后再次创建来进行测试。 如果不使用持久化 %SYS 功能,每次移除容器并启动新实例时,%SYS 内的任何更改都会丢失。

请注意,如果删除了 iris/ 文件夹,下次启动 IRIS 容器时,由于无法找到先前的 %SYS 数据,它将像在全新安装中一样进行初始化。 将创建一个全新的 iris/ 文件夹。

6. 使用 Docker Compose 

到目前为止,您一直在使用一个长命令 docker run 启动 InterSystems IRIS。 这虽然可行,但很快就会难以使用普通的 Shell 命令来管理一切。

Docker Compose 是一个 YAML 配置文件,用于定义如何运行一个或多个容器。这简化了整个应用程序栈的控制,使管理服务、网络和卷变得更加容易。 只需一个命令,即可从配置文件创建并启动所有服务。

以下是 Docker compose 的常用命令

命令描述
docker compose up -d以分离模式启动 docker-compose.yml 中定义的所有服务(默认情况下,使用当前文件夹中的 docker-compose.yml 文件)。
docker compose -f ./path/to/docker-compose.yml up -d从另一个目录中的 compose 文件启动服务。
docker compose down停止并移除由 docker compose up 创建的所有容器、网络和卷。
docker compose ps列出由 Compose 管理的容器。
docker compose logs查看 Compose 文件中定义的所有服务的日志。
docker compose logs <service>查看特定服务(例如,iris)的日志。
docker compose exec <service> bash在由 Compose 管理的正在运行的容器内打开一个 Shell。
docker compose stop停止正在运行的容器,但不将其移除。
docker compose start启动之前停止的容器。
docker compose restart重启 Compose 文件中定义的所有容器。
docker compose build构建或重建由 Dockerfile 定义的服务。
docker compose pull拉取服务的最新镜像。
docker compose config验证并查看 Compose 文件中的合并配置。

6.1 Docker Compose 示例

要使用 Docker Compose,必须创建一个 docker-compose.yml 文件,其中包含您要创建和启动的容器的所有配置。

这样一来,以下命令:

docker run --name my-iris -d --publish 9091:1972 --publish 9092:52773 --volume "C:\InterSystems\DockerTest:/durable" --env ISC_DATA_DIRECTORY=/durable/iris intersystems/iris-community:latest-cd --password-file /durable/password/password.txt

可被替换为下方的 docker-compose.yml

# docker-compose.yml     
services:
  iris:
    container_name: my-iris
    image: intersystems/iris-community:latest-cd
    init: true
    volumes:
      # System/persistent data (IRIS installation, databases, etc.)# On Windows, you can use either: "C:\\InterSystems\\DockerTest:/durable"
      - C:/InterSystems/DockerTest:/durable
    ports:
      - "9092:52773"# Management Portal / REST APIs
      - "9091:1972"# SuperServer port
    environment:
      - ISC_DATA_DIRECTORY=/durable/iris
    # Use the password file to log within the container
    command: --password-file /durable/password/password.txt

6.2 运行 Docker Compose 

在保存 Docker Compose 文件的目录中打开一个终端(或使用 -f 选项)并运行以下命令:

docker compose up -d

您的 IRIS 容器将以 Docker Compose 文件中指定的确切配置启动。

在 Docker Desktop 中,您现在可以看到一个名为“dockertest”的 Compose 栈(它采用保存 Docker Compose 的文件夹的名称)已经创建并与容器“my-iris”相关联:

7. 使用 Dockerfile 运行自定义源代码

到目前为止,您一直在直接从官方 Docker 镜像运行 InterSystems IRIS。 不过,在构建镜像时,我们可能需要自动加载镜像中的 ObjectScript 类或其他自定义代码。

Dockerfile是一个文本文件,其中包含从基础镜像(如 intersystems/iris-community:latest-cd)开始构建镜像的指令。 使用 Dockerfile,我们可以将自定义源代码添加到容器中,并在构建镜像时运行自定义命令。

7.1 Dockerfile 示例

下一个示例提供了一个执行以下操作的 Dockerfile:

  • 从官方 InterSystems IRIS 镜像启动镜像。
  • 将应用程序代码从 src/ 文件夹复制到容器。
  • 运行脚本来导入类并初始化容器化的应用程序,然后将日志保存到日志文件中。
  • 公开默认的 InterSystems IRIS 端口。

7.2 Docker Compose 示例

您还应当修改 Docker Compose,以指定从当前文件夹中的 Dockerfile 构建镜像:

# docker-compose.yml     
services:
  iris:
    container_name: my-iris
    build: # this tells Docker to build a new image based on the one specified in the Dockerfile
      context: .        # build the image from local Dockerfile
      dockerfile: Dockerfile
    image: my-modified-iris-image:latest   # give the new image a new tag to avoid overriding the base image
    init: true
    volumes:
      # System/persistent data (IRIS installation, databases, etc.)# On Windows, you can use either: "C:\\InterSystems\\DockerTest:/durable"
      - C:/InterSystems/DockerTest:/durable
    ports:
      - "9092:52773"# Management Portal / REST APIs
      - "9091:1972"# SuperServer port
    environment:
      - ISC_DATA_DIRECTORY=/durable/iris
    # Use the password file to log within the container
    命令:--password-file /durable/password/password.txt

7.3 了解层、镜像标记和构建与 运行时

在 Docker 中,正如什么是镜像?中所述,有两个重要的原则需要牢记:

  1. 镜像不可变:创建完镜像后,将无法进行修改。 您只能生成新的镜像或在镜像上添加更改。
  2. 容器镜像由层组成:每一层代表一组添加、移除或修改文件的文件系统更改。

执行 Dockerfile 中指定的指令时,新层会添加到镜像中。 这些层也将显示在镜像信息中。

考虑到这一点,务必区分 Docker 在构建时(当它从 Dockerfile 创建镜像时)和运行时(当它从该镜像启动容器时)的作用。

以下每个 Dockerfile 指令都在构建时执行:

  • COPY:将文件复制到镜像中
  • RUN:执行命令并将结果保存为新的镜像层
  • ENTRYPOINT:不改变文件系统,而是定义将在运行时启动的默认进程
  • EXPOSE:设置元数据,指示镜像打算使用哪些端口

运行时,Docker 不会重建镜像,而是在镜像上添加一个容器层。容器运行时所做的所有更改(如新文件、编辑、日志)都会进入这个临时层。

从上一个 Docker Compose 示例来看:

build: # this tells Docker to build a new image based on the one specified in the Dockerfile
  context: .        # build the image from local Dockerfile
  dockerfile: Dockerfile
image: my-modified-iris-image:latest   # give the new image a new tag to avoid overriding the base image

这些指令通过拉取基础镜像并按照 Dockerfile 中的描述进行修改,告知 Docker 创建一个名为“my-modified-iris-image:latest”的新镜像(这称为标签)。 用其他名称标记新镜像非常重要。如果我们不在新创建的镜像上放置标签,基础镜像会被新镜像覆盖。 官方镜像仍在 Docker Hub 上提供,但此本地版本会对其进行映射,并且每个引用该标签的项目现在都会不知不觉地使用包含多个新层的自定义镜像。

为了避免这种情况,请务必使用不同的标签来创建新的单独镜像,同时确保官方基础镜像干净、可重用。

7.4 源代码和初始化脚本

此时,我们应至少创建一个类,并将其放在 src/ 文件夹中。 该类将被复制到容器中,并通过 iris.script 文件导入,该文件包含在构建镜像时导入类和初始化应用程序所需的所有指令。

在项目文件夹中创建一个名为 src/DockerStepByStep 的新目录并创建以下类文件:

Class DockerStepByStep.cheers Extends%RegisteredObject
{

ClassMethod sayHi() As%Status { Set sc = $$$OKw"Hi mom!",! Return sc }

}

在项目的根目录中,创建一个名为 iris.script 的文件:

// Unexpire passwords for dev modezn"%SYS"Do##class(Security.Users).UnExpireUserPasswords("*")

// Load classes from durable sourcezn"USER"// Import classesset importPath = "/opt/irisapp/src"write"Loading classes at '", importPath, "' ...", ! set errors = ""do$System.OBJ.Import(importPath,"cuk",,.errors) if errors = 0 { write"Classes loaded successfully", ! } else { write errors, " errors occurred while loading classes!", ! }

halt

7.5 使用 Dockerfile 构建镜像

首次运行时,您可以使用以下命令从 Dockerfile 构建镜像(--build 标记会强制 Docker 从您的 Dockerfile 重建镜像):

docker-compose up --build

对于其他运行,如果 Dockerfile 未被修改,则可以简单地运行:

docker-compose up -d

开始构建镜像后,您会在终端中看到以下日志:

PS C:\InterSystems\DockerTest> docker-compose up --build
[+] Building 21.5s (13/13) FINISHED
 => [internal] load local bake definitions                                                                     0.0s
 => => reading from stdin 530B                                                                                 0.0s
 => [internal] load build definition from Dockerfile                                                           0.0s
 => => transferring dockerfile: 1.73kB                                                                         0.0s
 => [internal] load metadata for docker.io/intersystems/iris-community:latest-cd                              10.0s
 => [internal] load .dockerignore                                                                              0.0s
 => => transferring context: 2B                                                                                0.0s 
 => [1/6] FROM docker.io/intersystems/iris-community:latest-cd@sha256:93488df381f5868649e7bfc33a9083a3e86a22d  0.9s 
 => => resolve docker.io/intersystems/iris-community:latest-cd@sha256:93488df381f5868649e7bfc33a9083a3e86a22d  0.0s 
 => [internal] load build context                                                                              0.0s 
 => => transferring context: 147B                                                                              0.0s
 => [2/6] WORKDIR /opt/irisapp                                                                                 0.0s
 => [3/6] COPY src src                                                                                         0.1s 
 => [4/6] COPY iris.script .                                                                                   0.1s
 => [5/6] RUN mkdir -p /opt/irisapp/logs                                                                       0.3s
 => [6/6] RUN iris start IRIS &&     iris session IRIS < iris.script > /opt/irisapp/logs/build.log 2>&1 &&     4.5s 
 => exporting to image                                                                                         4.5s 
 => => exporting layers                                                                                        3.3s 
 => => exporting manifest sha256:3ce316cefa21a3707251c4287005a15b02e6dc0151b24baf2a82f76064792250              0.0s 
 => => exporting config sha256:00238e19edef86b29149d2eb89ff75f4d1465ba0d9a2ac4494a14d3bd3746a94                0.0s 
 => => exporting attestation manifest sha256:3579cab5c8accc7958090276deb60bd7dbbc2ecbf13af8e7fa8c4ff2dfe91028  0.0s 
 => => exporting manifest list sha256:17b969c340f57d611cc7603287cc6db50cffd696258a72b5648ece0a919676ac         0.0s 
 => => naming to docker.io/intersystems/iris-community:latest-cd                                               0.0s 
 => => unpacking to docker.io/intersystems/iris-community:latest-cd                                            0.9s 
 => resolving provenance for metadata file                                                                     0.0s 
[+] Running 3/3
 ✔ intersystems/iris-community:latest-cd  Built                                                                0.0s 
 ✔ Network dockertest_default             Created                                                              0.1s 
 ✔ Container my-iris                      Created                                                              0.2s 

在第 6/6 步中,iris.script 文件被执行到容器化的 IRIS 实例中,日志保存在路径 /opt/irisapp/logs/build.log 中。

要查看日志,可以运行以下指令:

docker exec -it my-iris cat /opt/irisapp/logs/build.log

您应当看到以下记录,这些记录会告知您类编译的结果:

Node: buildkitsandbox, Instance: IRIS

USER>

USER>

%SYS>

%SYS>

%SYS>

%SYS>

USER>

USER>

USER>

USER> Loading classes at '/opt/irisapp/src' ...

USER>

USER>

Load of directory started on 09/16/202507:46:28 Loading file /opt/irisapp/src/DockerStepByStep/cheers.cls as udl

Compilation started on 09/16/202507:46:28 with qualifiers 'cuk' Class DockerStepByStep.cheers is up-to-date. 编译在 0.005s 内成功完成。

Load finished successfully.

USER> Classes loaded successfully

USER>

USER>

在 Docker Desktop 上,您可以看到一个名为“my-modified-iris-image”的新镜像已创建,并且正在与基础官方镜像一起运行。

如果检查这些镜像,您会发现自定义镜像由 31 层组成,而不是原始镜像的 25 层。 新层与 Dockerfile 在构建时执行的指令相对应:

7.6 在容器化 IRIS 终端中运行指令

要测试这些类,您可以在容器化 IRIS 实例中激活 IRIS 终端。 为此,请执行以下指令:

docker exec -it my-iris iris session IRIS

此时,您可以使用以下命令从 USER 命名空间调用 ClassMethod:

do##class(DockerStepByStep.cheers).sayHi()

最后,您应当看到以下输出:

PS C:\InterSystems\DockerTest> docker exec -it my-iris iris session IRIS

Node: 41c3c7a9f2e4, Instance: IRIS

USER>do##class(DockerStepByStep.cheers).sayHi() Hi mom!

8. 结语和未来计划

我们已经完成了在 Docker 中运行 InterSystems IRIS 的整个周期:

  • 拉取镜像
  • 启动并配置容器
  • 使用持久化 %SYS 来持久化数据
  • 使用自己的代码和脚本构建自定义镜像

以上内容足以让您在容器化环境中试验 IRIS 并将其用于开发。

您可以访问 GitHub 仓库,其中包含最后一部分讨论的所有文件(Docker Compose、Dockerfile、iris.script 等)。

敬请期待下一篇文章!

1
0 15
文章 Lilian Huang · 十一月 6, 2025 6m read

我很清楚对于那些完全不熟悉 VS Code、Git、Docker、FHIR 和其他工具的人来说,设置环境时会遇到一些困难。 所以我决定写这篇文章,详细介绍整个设置过程,以便大家能够轻松上手。

如果您能在本文最后留下评论,告诉我说明是否清楚,是否有遗漏,或者是否有其他您觉得有用的东西,我将不胜感激。

设置包括:

✅ VS Code – 代码编辑器
✅ Git – 版本控制系统
✅ Docker – 运行 IRIS for Health Community 的实例
✅ VS Code REST 客户端扩展程序 – 用于运行 FHIR API 查询
✅ Python – 用于编写基于 FHIR 的脚本
✅ Jupyter Notebook – 用于 AI 和 FHIR 任务

准备工作:确保您在系统上拥有管理员权限

除了阅读本指南,您还可以按照视频中的步骤操作:

如果您是 Windows 系统(请注意:原文是YouTube视频,请跳转至EN原帖查看)

0
0 13
InterSystems 官方 Jeff Liu · 三月 3, 2025

首先,祝开发者社区的各位成员新年快乐! 我们希望今年为大家带来更多好东西,今天我想介绍 VS Code的最新版 Intersystems Language Server 扩展程序。 大多数 Language Server 改进都可以通过 ObjectScript 扩展 UI 体验到,因此您可能不知道 2024 年我们发布了 Intellisense 和鼠标悬停等方面的许多改进。 请快速浏览 Language Server 更新日志 看看您错过了什么。 最近发布的2.7.0 版本带来了对 Windows ARM 平台的支持,因此,如果您使用 Surface Pro 11 这类设备(我正在用这台设备愉快地写这篇帖子),那么您现在可以在您的设备上获得出色的 ObjectScript 开发体验。 赶快试用一下,并在下方评论区中分享您的使用心得。

0
0 89
InterSystems 官方 Michael Lei · 一月 7, 2025

我们已经有一段时间没有在开发者社区上发表关于嵌入式 Git 的文章了,我想借此机会更新一下今年我们完成的大量工作以及未来的工作计划。

背景信息

如果您要在 IRIS 上构建解决方案,并想要使用 Git,那就太棒了! 只需将 VSCode 与本地 Git 仓库结合使用,并将更改推送到服务器上即可,就是这么简单。

但在以下使用场景中该怎么办:

  • 您与其他开发者在共享的远程开发环境中合作,并想要避免因同时编辑同一文件而影响彼此的工作
  • 您使用位于管理门户中的编辑器来实现互操作性或业务智能,并希望对您的工作直接进行源代码控制,即使在本地容器中也希望如此
  • 您仍在使用 Studio 处理一些任务并且/或偶尔会再次从 VSCode 跳转回 Studio;或者您的团队还没有完全接受 VSCode,一些团队成员仍想使用 Studio,而其他人在使用 VSCode
  • 您同时在同一命名空间中处理多个独立的项目,例如使用 InterSystems Package Manager 定义的多个软件包,并想仅通过一个 isfs 编辑视图使用所有软件包(而不是在多个单独的项目中使用),同时在合适的本地 git 仓库中自动跟踪更改

在以上任何情况下,您都非常需要嵌入式源代码控制。 您可能听说过“服务器端源代码控制”或“源代码控制挂钩”这类叫法,它们的含义相同,都表示可在所有编辑器(包括 IDE 和图形编辑器)中对 IRIS 实例实现一致的源代码控制行为。 所有控制操作都是针对与您的 IRIS 实例位于同一位置的源代码控制仓库执行的,该仓库可能位于远程服务器上、您自己的机器上,甚至可能位于容器中。

如果您希望开始使用 Git 进行嵌入式源代码控制,可以先从嵌入式 Git (https://github.com/intersystems/git-source-control) 着手。 嵌入式 Git 不是 InterSystems 支持的产品,但得到了 InterSystems 内我的团队(应用程序服务团队)和广大用户社区的大力支持。 我们始终欢迎大家提出 PR 和 GitHub 议题,我们会监控开发者社区活动(特别是使用相对较新的“嵌入式 Git”标签)。

2024 年嵌入式 Git 工作回顾

2024 年初,我曾向已能轻松使用 Git 并愿意在必要时进行深入研究、更偏向技术型的用户推荐嵌入式 Git。 现在,我极力推荐所有人使用嵌入式 Git。 为了展示我们对此工具倾注的心血以及我们在 2024 年取得的飞跃,下方是过去几年的提交量图:

如果您想了解我们的最新动态,可以查看版本或我们的变更日志,但下面是对要点的总结:

  • 7 月,我们添加了“基本模式”(具体说明请参阅此处),其中的“同步”操作可以简化拉取/提交/变基/推送工作流,我们推荐大家在一般情况下使用该模式,尤其是那些不太熟悉 Git 的用户。
  • 在多个版本中,我们将 git 拉取和签出操作(实际上是任何修改 Git 仓库状态的操作)无缝同步回 IRIS,从而无需强制重新加载整个代码库便可确保所有内容均为最新状态。
  • 在我们的 9 月版本中,通过从管理门户下载 VSCode 工作空间文件,您可以非常轻松地建立 isfs 连接。
  • 在我们的 11 月版本中,可以通过扩展设置页面进行更多配置,无需在终端运行命令,并针对互操作性设置中的两种最常见(几乎一定会出现)的用例增加了智能合并冲突解决功能。
  • 除了以上工作之外,我们还解决了数十个小错误和实用性问题,简化了管理门户的导航,并增加了很多小功能,以简化互操作性用例以及跨多个开发者特定命名空间在共享远程实例上的协作(我们认为这是一种常用方式,并推荐大家使用)。

即将推出

下一个版本 (2.8.0) 预计在两周内发布,其中将包含我们历经数月开发出的“生产分解”功能。 互操作性生产通常以单个文件的形式进行源代码控制,由于一次只能由一人编辑生产,这会导致并发问题。 共享开发环境中还存在一些合并问题,这些问题几乎一定会出现,虽然我们可以通过智能化方式解决它们,但在某些分支工作流中,这些问题很可能会继续出现。 利用生产分解功能,每个业务主机(服务、进程或操作)在源代码控制中都会以单个文件的形式表示。 如果您有兴趣尝试此功能,请联系我们!

进入 2025 年,我们将继续保持嵌入式 Git 的发展势头,重点关注其他身份验证方法并支持其他常见部署模式。 您可以访问 2025 H1 里程碑了解我们的大致计划(其中包括几次版本发布;我们通常会每月发布次要版本,并根据需要发布补丁版本修复重要错误)。

如果您有兴趣深入了解开发细节/获取最新开发信息,欢迎加入我们每周五召开的利益相关者会议。 此会议也成为了嵌入式 Git 的一种“办公时间”。 请随时留言告诉我您的电子邮件地址,我会邀请您加入会议。

0
0 95
文章 Hao Ma · 十一月 22, 2023 5m read

介绍

由于InterSystems最近宣布从2023.2版本开始停止对InterSystems Studio的支持,转而独家开发Visual Studio Code(VSC)IDE的扩展,相信后者比Studio提供了更优越的体验,我们很多开发者都已切换或开始使用 VSC。很多人可能想知道如何打开终端进行操作,因为VSC没有像Studio那样的输出面板,也没有集成的功能来打开IRIS终端,除非下载InterSystems开发的插件。

概括

  • 介绍
  • 解决方案
    • 对于至少具有 IRIS 2020.1 或 IRIS IRIS 2021.1.2 的用户– 使用 Web 终端
    • 对于至少具有 IRIS 2023.2 的用户 – 使用 WebSocket 终端
    • 对于使用基于 Docker 的 IRIS 的用户
    • 对于在本地计算机上使用 2023.2 之前的 IRIS 版本的用户
    • 对于使用 SSH 连接在基于远程服务器的 IRIS 上进行编码的用户

解决方案

在 VSC 中打开终端的方法有多种,具体取决于您使用的具体配置,我在这里总结了适合任何情况的最佳解决方案:

对于至少具有 IRIS 2020.1.1 或 IRIS 2021.1.2 的用户 – 使用 Web 终端

1
0 385
文章 Weiwei Gu · 九月 14, 2023 2m read

InterSystems 还发布了容器化部署的IRIS。这篇文章旨在演示 InterSystems IRIS 和依赖 IRIS 后端的应用程序如何打包到镜像中并在容器中的其他计算机中运行,以及这样做有多么简单。

容器运行包含所有必需的可执行文件、二进制代码、库和配置文件的镜像。镜像可以从一台机器移动到另一台机器,像 Docker Hub 这样的镜像存储库可以简化这个过程。

我在本演示中使用了 Open Exchange 的应用程序。

演示视频:https://www.loom.com/share/93f9a760b5f54c0a8811b7a212387b9d

IRIS 数据平台社区版的镜像(image)可以在 InterSystems 容器注册表中找到:

https: //containers.intersystems.com/contents

为了在主机中使用 IRIS 的容器化实例,应在运行时拉取它。

为此,Dockerfile 需要具有以下命令,如下所示:

Dockerfile:

Dockerfile

0
0 208
文章 Weiwei Gu · 九月 14, 2023 1m read

昨天,我在一个客户网站提供从 Studio 迁移到 VS Code 的定制咨询时,就遇到了这种情况。

该站点的服务器已配置为使用delegated authentication,但尚未针对 /api/atelier Web 应用程序设置“delegated”复选框,而 InterSystems ObjectScript 扩展包的成员正是使用该复选框进行连接的。

一旦我们的应用程序设置了其复选框并单击了服务器管理器刷新按钮,就可以在服务器上枚举命名空间。

0
0 147
公告 Michael Lei · 六月 8, 2023

如果您已经使用%UnitTest 框架构建了单元测试,或者正在考虑这样做,请查看InterSystems 测试管理器Test Manager

无需离开 VS Code,您现在可以浏览单元测试、运行或调试它们,并查看之前的运行结果。

InterSystems 测试管理器适用于 ObjectScript 扩展支持的两种源代码位置范例。您的单元测试类可以在 VS Code 的本地文件系统(“客户端编辑”范例)或服务器命名空间(“服务器端编辑”)中掌握。在这两种情况下,实际测试运行都发生在服务器命名空间中。

欢迎反馈。

0
0 139
文章 Michael Lei · 二月 19, 2023 1m read

各位开发者,大家好!

对我来说,关于 ObjectScript 的最痛苦的一件事是输入 ##class(Class).Method() 以在代码或终端中调用类方法。 为解决这个问题, 我甚至提出了一个在 ObjectScript 中简化它的想法

但是 VSCode ObjectScript中有一个刚刚引入到插件中的新功能 – 复制调用Copy Invocation!

只需将 **Copy Invocation**(复制调用)链接悬停在代码中的每个类方法上方,点击它,该调用就会被复制到缓冲区:

将其粘贴到想要执行的任何位置!!

USER>w ##class(dc.sample.ObjectScript).Test()

就到这儿!

这里是显示其运作方式的[视频]。

非常感谢 VSCode 贡献者

祝您编程愉快!

0
0 328
文章 Michael Lei · 十二月 13, 2022 7m read

嵌入式 Python 模板

今天你们分享一个简单的嵌入式 Python 模板,我建议将其作为任何使用 InterSystems IRIS 并将使用嵌入式 Python 的通用项目的起点。

功能:

  • 随时可用的嵌入式 Python;
  • 3 种嵌入式 Python 开发方式示例;
  • 随时可用的 VSCode 开发;
  • 支持 Docker;
  • 支持在线演示;
  • 随时可用的 ZPM 优先开发。

下面讨论一下这些功能!

我们先来谈谈嵌入式 Python。 此功能在 InterSystems IRIS 2021.2 中提供,它允许使用 InterSystems IRIS 通过 Python 开发解决方案。 IRIS 2021.2 及以上版本允许使用 InterSystems IRIS 在共享内存环境中执行 Python 脚本,这为 Python 开发者在使用代码与数据相近的数据库时提供了独特的选项。 

3 种使用嵌入式 Python 进行开发的模式

从 ObjectScript 调用 Python 库

此操作因 %SYS.Python 类而变为可能,该类允许导入 Python 库并通过 ObjectScirpt 调用 Python。 文档示例。 请查看以下代码:

&lt;span class="hljs-keyword">ClassMethod&lt;/span> Today() &lt;span class="hljs-keyword">As&lt;/span> &lt;span class="hljs-built_in">%Status&lt;/span>
{
  &lt;span class="hljs-keyword">Set&lt;/span> sc = &lt;span class="hljs-built_in">$$$OK&lt;/span>
  &lt;span class="hljs-keyword">Set&lt;/span> dt = &lt;span class="hljs-keyword">##class&lt;/span>(&lt;span class="hljs-built_in">%SYS.Python&lt;/span>).Import(&lt;span class="hljs-string">"datetime"&lt;/span>)
  &lt;span class="hljs-keyword">write&lt;/span> dt.date.today().isoformat()
  &lt;span class="hljs-keyword">Return&lt;/span> sc
}

使用 Python 编写 ObjectScript 类方法

事实上,现在开发者可以使用纯 Python 在方法签名和代码中添加 [Language=python] 标签。 还有一个辅助 Python 库“iris”,可以用于引用 ObjectScript 类和全局变量。 文档示例、示例代码:

ClassMethod CreateRecordPython(propValue As %VarString, ByRef id As %Integer) [ Language = python ]
{
    &lt;span class="hljs-keyword">import&lt;/span> iris
    obj=iris.cls(__name__)._New()
    obj.Test=propValue
    sc=obj._Save()
    id=obj._Id()
    &lt;span class="hljs-keyword">return&lt;/span> sc
}

使用纯 Python 编写 InterSystems IRIS 解决方案代码

这是开发者可以选择的第三种处理 IRIS 的方式。  这里,Python 脚本需要连接到 IRIS,此操作可以通过环境变量和设为“On”的 CallIn 服务来完成,请参见下面的详细信息。 设置完后,使用 IRIS 在共享内存中执行 Python 脚本。 在这里,“iris”库也非常有用。 文档示例。 

&lt;span class="hljs-function">&lt;span class="hljs-keyword">def&lt;/span> &lt;span class="hljs-title">create_rec&lt;/span>&lt;span class="hljs-params">(var)&lt;/span>:&lt;/span>
    obj=iris.cls(&lt;span class="hljs-string">'dc.python.PersistentClass'&lt;/span>)._New()
    obj.Test=var
    obj._Save()
    id=obj._Id()
    &lt;span class="hljs-keyword">return&lt;/span> id

&lt;span class="hljs-comment"># test record creation&lt;/span>
&lt;span class="hljs-keyword">from&lt;/span> datetime &lt;span class="hljs-keyword">import&lt;/span> datetime
now=str(datetime.now())
print(&lt;span class="hljs-string">"Creating new record in dc.python.PersistentClass"&lt;/span>)
print(create_rec(now))

&lt;span class="hljs-comment">## run SQL and print data&lt;/span>
&lt;span class="hljs-function">&lt;span class="hljs-keyword">def&lt;/span> &lt;span class="hljs-title">run_sql&lt;/span>&lt;span class="hljs-params">(query)&lt;/span>:&lt;/span>
    rs=iris.sql.exec(query)
    &lt;span class="hljs-keyword">for&lt;/span> idx, row &lt;span class="hljs-keyword">in&lt;/span> enumerate(rs):
        print(&lt;span class="hljs-string">f"[&lt;span class="hljs-subst">{idx}&lt;/span>]: &lt;span class="hljs-subst">{row}&lt;/span>"&lt;/span>)

query=&lt;span class="hljs-string">"Select * from dc_python.PersistentClass"&lt;/span>
print(&lt;span class="hljs-string">"Running SQL query "&lt;/span>+query)
run_sql(query)

支持 Docker

模板仓库在容器中运行 IRIS,并设置嵌入式 Python 调整所需的所有内容。 

环境变量。 嵌入式 Python 需要设置特定的环境变量来连接到 IRIS 并运行 Python 脚本。 下面是 dockerfile 中有帮助的设置:

# init Python env
ENV PYTHON_PATH=/usr/irissys/bin/irispython
ENV SRC_PATH=/irisrun/repo
ENV IRISUSERNAME "SuperUser"
ENV IRISPASSWORD "SYS"
ENV IRISNAMESPACE "USER"

此外,嵌入式 Python 需要将 CallIn 服务设为“on”,此操作在构建 docker 的阶段在 iris.script 中完成:

&lt;span class="hljs-comment">; enabling callin for Embedded Python&lt;/span>
    &lt;span class="hljs-keyword">do&lt;/span> &lt;span class="hljs-keyword">##class&lt;/span>(Security.Services).Get(&lt;span class="hljs-string">"%Service_CallIn"&lt;/span>,.prop)
    &lt;span class="hljs-keyword">set&lt;/span> prop(&lt;span class="hljs-string">"Enabled"&lt;/span>)=&lt;span class="hljs-number">1&lt;/span>
    &lt;span class="hljs-keyword">set&lt;/span> prop(&lt;span class="hljs-string">"AutheEnabled"&lt;/span>)=&lt;span class="hljs-number">48&lt;/span>
    &lt;span class="hljs-keyword">do&lt;/span> &lt;span class="hljs-keyword">##class&lt;/span>(Security.Services).Modify(&lt;span class="hljs-string">"%Service_CallIn"&lt;/span>,.prop)

另外,您的解决方案可能需要安装一些 Python 库。 这通过仓库根目录中的 requirements.txtdockerfile 中的 pip3 调用来实现:

pip3 install -r requirements.txt && \

随时可用的 VSCode 开发

使用 docker 在 VSCode 中开发非常方便。 如果想要在 docker IRIS 解决方案中使用嵌入式 Python 进行开发,VSCode 需要切换到 Devcontainer 模式。 为此,将 devcontainer.json 文件添加到 .devcontainer 文件夹中。 该文件描述了需要使用的 docker 服务(本例中为 iris),这可以帮助在 VSCode 中运行 Python 脚本,这些脚本将由在容器中运行的 IRIS 使用的 Python 引擎提供服务。 devcontainer.json 文件还有一个部分,其中说明了需要在容器模式下使用哪些扩展

"extensions": [
        "ms-python.python",
        "ms-python.vscode-pylance",
        "intersystems-community.vscode-objectscript",
        "intersystems.language-server",
        "intersystems-community.servermanager",
        "ms-vscode.docker"
    ],

通过 ZPM 安装嵌入式 Python 解决方案

此模板被设置为“ZPM 优先”开发仓库。 这意味着所有开发代码都已在 module.xml 中介绍,并且每次构建 docker 镜像时都作为 ZPM 模块安装,开发者每次编码时都在 iris.script 中使用以下行开头:

zpm "load /home/irisowner/irisbuild/ -v":1:1

ZPM 模块中还介绍了嵌入式 Python 代码,它通过 FILECOPY 进行安装:

&lt;FileCopy Name="python/" Target="${libdir}python/"/>

此表达式表示,我们想要将所有 Python 脚本打包在仓库中的 /python 文件夹下,并将其安装在目标 IRIS 安装程序的 libdir 的 python/ 文件夹中。 如果将 Python 脚本复制到 ${libdir}python/ 文件夹下,则可以在目标 IRIS 机器中通过 ObjectScirpt 或 Python 对其进行导入调用。

注意: 确保您的文件夹名称唯一,以免意外替换其他 Python 代码。

希望该模板对您有用。 欢迎提供反馈,尤其是拉取请求!

0
0 242
文章 Hao Ma · 十一月 14, 2022 7m read

ZPM介绍

有Developer听闻了InterSystems的包管理器ZPM, 希望我能介绍一下。正好刚刚看到一个开发者论坛的新闻: Open Exchange ZPM is now InterSystems Package Manager , 觉得更有必要了。

zpm是什么

简单说:zpm, 全称InterSystems ObjectScript Package Manager, 是一个包管理器, 开发者是Nikolay Soloviev和Dmitry Maslennikov。它先是在开发者社区里得到认可,以至于InterSystems开发者社区最近的一些比赛,要求参赛作品用zpm打包。然后就有了上面的链接的内容:InterSystems决定把它做为自己官方的打包工具, 将它改名字叫IPM(InterSystems Package Manager),同时保持它的开源状况不变。

这里我还是用zpm称呼它。两个原因。1. 操作的命令还是zpm, 所谓ipm,只是官方给的名字。2. ipm新的注册中心还不太了解,而且到目前为止,IPM的注册中心还只对自己的雇员和付费用户开放。本文的读者应该都还没来得及付费,所以暂时先放放,还是叫它zpm。

考虑到没有程序员背景的读者而对包管理器不熟悉,啰嗦两句。

什么是包管理器

大多数开发工具都有自己的包管理器,Java开发使用MAVEN, Python用PIP, NodeJS使用npm, 它们细节有区别,功能大致是一致的,就是安装管理程序包,最基本的工作是:

  1. 找到自己要的程序包。 简单的命令能让你在网上找到它,用名字找,或者其他方法搜索。
  2. 安装包。
    • 这里面最重要的是发现包之间的依赖。比如你要装一个软件包叫“包饺子”,作者在开发的时候使用了另一个软件叫“和面”,这个“和面”可能是作者自己写的,或者是网上其他人写的,注册在包管理器的。这时候作者在”包饺子“里声明,我依赖”和面“。 那么,当您去下载安装"包饺子“的时候,包管理器会自动的把”和面“也给你下载并安装上。
  3. 管理包: 比如升级,删除等等。

ZPM的特点

没有zpm的时候,人们是怎么传递ObjectScript代码的? 大概是这样:发布者把代码从studio导出成一个XML;接受者拿到这个xml, 然后使用Studio或者iris管理门户把它导入到一个命名空间。

这里面有两个问题:1. 麻烦, 2. 没有打包各种类型文件的能力。通常一个项目,除非是只使用ObjectScript, 多数都用到各种文件:前端的css, html, javascript, 图片; 各种配置文件xml或者yaml, 其他语言的包 (iris支持嵌入式python,以及集成多种编程语言工作)等等。

ZPM是怎么工作的?

  1. 作者把自己的数据放在一个公网地址上,比如github; 使用zpm生成一个配置文件(module.xml); 把module.xml发布到zpm的registry, 让别人能找到你的软件包。
  2. 使用者在Registry搜寻并下载这个程序包,zpm命令自动把它导入到IRIS的一个命名空间。

为什么能自动导入到iris ? 这里有个ZPM和其他包管理器的很大的区别: ZPM命令是在IRIS的terminal里执行的, 而不是操作系统上。

还有一个特点:zpm的设计假设大家开发代码使用的IDE是VSCode而不是Studio,这非常关键。Studio上的开发是在服务端的开发,没有一个类应该存在哪个文件目录的概念。VSCode相反,你创建一个类:Demo.Web.Test, 那么默认的文件保存是在一个这样的目录下: ./src/Dome/Web/Test.cls

不遵循这样的目录结构,您要额外做很多手工的调整才能使用zpm保存加载程序包。

这里还有很多问题, 我们后面详细说。

ZPM的下载安装

您可以从github上的InterSystems-Community用户的zpm Repo下载zpm-xxx.xml文件, 其中xxx是版本号, 当前(2022年10月)最新的版本是0.4.0。 把下载的xml文件导入到IRIS的任何命名空间。这样安装就成功了。

要下载安装软件的时候,您要先进入安装目标的命名空间(比如下面的USER),然后输入zpm, 也就进入了ZPM的操作界面: ZPM Shell

USER>zpm

=============================================================================
|| Welcome to the Package Manager Shell (ZPM).                             ||
|| Enter q/quit to exit the shell. Enter ?/help to view available commands ||
=============================================================================
zpm:USER>

输入help, 您可以看到帮助文件。(帮助文件很长, 我只贴一小段。)

zpm:USER>help -v

Available commands:
NOTE: [] around a parameter indicates it is optional
arrange [flags] [<module>]
  ■ Description: Rearranges the resources in a module manifest to follow the standard format
# 此处省略许多行
........
For more detail, run:
  help <command-name>
or
  help -v
zpm:USER>

接着, 我相信您一定想看看安装命令是怎么执行的,比如这样:

zpm:USER>help install
install [flags] <module> [<version>]
...此处省略若干行...
  ■ Examples
    ∙ install HS.JSON 1.x
      Installs the most recent 1.x version of HS.JSON available in any configured repository in the current namespace.
zpm:USER>quit
USER>

好吧,让我们来下载一个最受欢迎的开发者应用“webTerminal”,了解最基本的zpm操作。

最基本的ZPM操作

搜索package

输入zpm:USER>search或者, 您可以使用zpm:USER>search -r,“-r"显示数据包所在的repo的位置。我没有贴在这里是因为显示的内容太宽了。在我的帖子的代码框里显示看上去有点乱。

zpm:USER>zpm:USER>search
registry https://pm.community.intersystems.com:
alwo-goselector                                1.0.1
analytics-okr                                  1.0.0
...此处省略许多行...
zpm-shields                                    1.0.1
zpmhub                                         0.3.1
zpmshow                                        1.0.3
zpm:USER>

除了search, 还有个find命令。 它可以使用*,但无法忽略大小写。

zpm:USER>find *Webt*
registry https://pm.community.intersystems.com:

zpm:USER>find *webt*
registry https://pm.community.intersystems.com:
webterminal 4.9.6
zpm:USER>

安装package

zpm:USER>install webterminal
...(省略若干行)...
WebTerminal package successfully mapped into all namespaces.
[USER|webterminal]	Compile SUCCESS
[USER|webterminal]	Activate START
[USER|webterminal]	Configure START
[USER|webterminal]	Configure SUCCESS
[USER|webterminal]	Activate SUCCESS
zpm:USER>

到这里, 我来再次总结一下ZPM的最基本的功能:原本您想要使用一个其他开发者使用的程序,您要把它从某处,比如一个帖子,InterSystems的OpenExchange网站,或者一个github的主页上下载程序(XML文件),然后导入到IRIS执行。有了ZPM, 你可以在IRIS的terminal里通过ZPM命令,直接获得这个程序并执行。前提是:作者的程序是用ZPM打包并放在ZPM注册中心。

来先了解一下ZMP的注册中心

注册中心(Registry)

默认安装下, zpm的注册中心是这样的

zpm:USER>repo -list
registry
	Source: 		https://pm.community.intersystems.com
	Enabled?		Yes
	Available?		Yes
	Use for Snapshots?	Yes
	Use for Prereleases?	Yes
	Is Read-Only?		No
	Deployment Enabled? 	No

zpm:USER>

这也是当前zpm唯一的一个注册中心(配置私服会在后面介绍), 组册的软件包是最近一些年社区开发者写的各种工具和示例代码。说一下它的当前状况:

  • 当前能下载到278个软件包。
  • 所有的包都放在了github。
  • 包都很新。 这么说吧,release能到2.0的都是凤毛麟角

这里有个让人意外的事。我安装完webterminal并开始使用的时候,浏览器跳出这个提示。 “Welcome to WebTerminal! ...New update is available. ”。这说明这个registry并没有给出最新的webterminal版本。 我有点好奇,去看了一下webterminal的github page, 发现WebTerminal当前的版本是4.9.5。而zpm registry上下载的版本是4.9.2, 发行于2019年。

webterminal是一个前台工具,作者理所当然的的在代码里做了版本更新的检查并提醒了用户。而对于纯后台的ObjectScript语言的代码, 我估计大多数程序员都做不到这一点。 那么如果要保证其他人看到的是新版的软件, 就要求软件的作者,除了更新自己Github上的代码,还要把新版本及时更新在zpm的注册中心上。

文章太长了, 先贴一部分,后面会介绍

  • 软件的发布
  • 定义软件包的依赖
  • 配置私服

to be continued

1
0 322
文章 王喆 👀 · 九月 7, 2022 4m read

前言

自接触IRIS以来在医院之中使用最多的是其作为一个ESB集成引擎来使用,作为医院的集成平台+数据中心中的一环。但是其也可以进行CRUD作为前后端分离项目的后端使用:

文章目录

前言

文章目录

一、开发技术和工具

二、开发路径和相关代码

       1.数据库

       2.准备工作

       3.开发接口的相关步骤

       4.成果展示

总结

本文章将以一个简单的页面展示IRIS的相关CRUD操作:

是的,我计划使用IRIS重构Production页面,先展示一下我开发完的成果吧:

呃の好像是一毛一样,哈哈

一、开发技术和工具

工欲善其事,比先利其器:

后端:HealthConnect+Global
前端:vue

使用IRIS%CSP.REST开发的Rest API接口,前端使用vue简单的把接口相关内容展示,可以编辑、新增组件,控制production启动、停止、更新检测状态。

二、开发路径和相关代码

1.数据库

首先,我们找到Production的相关表,分别是:Ens_Config.Item Ens_Config.Production 如图所示:

所以代码的思路很明确了对Ens_Config.Item进行新增、删除、修改、查询操作对Ens_Config.Production进行查询操作。

2.准备工作

在正式开发之前我们得先做一些准备工作:比如开放网关

7
6 625
文章 王喆 👀 · 九月 18, 2022 4m read

       这是一篇笔记:

说明

       Restful是一种基于Http的网络应用程序的设计风格和开发方式,可以使用xml格式或者Json格式定义。

RESTFUL特点包括:

1、每一个URI代表1种资源;

2、客户端使用GETPOSTPUTDELETE4个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源;

3、通过操作资源的表现形式来操作资源;

4、资源的表现形式是XML或者HTML

5、客户端与服务端之间的交互在请求之间是无状态的,从客户端到服务端的每个请求都必须包含理解请求所必需的信息。

IRIS中实现

GET

0
0 244
文章 Michael Lei · 八月 19, 2022 2m read

我很高兴与大家分享我第一次使用docker容器版本的IRIS for Health的经验,以探索你对使用或试用的兴趣,利用docker容器的优势,它是轻量级的,易于部署。本文将通过使用Renan Lourenco编写的名为ENSDEMO的GitHub仓库的实施步骤。

设置IRIS for Health社区版docker容器环境的步骤:

  1. 启动运行Docker
  2. 下载docker 镜像image

docker pull containers.intersystems.com/intersystems/irishealth-community:2022.2.0.304.0

  1. 从GitHub 克隆源repository

git clone https://github.com/OneLastTry/irishealth-ensdemo

  1. 改一下文件目录.
  2. 从docker-compose.yml建立容器镜像

docker-compose build

  1. 运行你的容器

docker-compose up -d

在我最初的尝试中,我无法下载irishealth community:2022.2.0.304.0的确切版本,因为它在ENSDEMO的最初发布中已经发生了变化。修复方法是,当试图从InterSystems容器注册表拉出docker镜像时,在注册表中拉出最新的可用标签。

2
0 503
文章 Michael Lei · 八月 9, 2022 1m read

不久前,GitHub推出了在浏览器中快速运行VSCode的功能,可以在任何仓库中运行。 在任何仓库或拉动请求上按下 . 键,或将URL中的.com换成.dev,就可以直接进入浏览器中的VS Code环境。

github dev

这个VSCode是桌面版的轻型版本,完全基于浏览器。由于这个原因,它对允许以这种方式工作的扩展插件有限制。让我介绍一下VSCode-ObjectScript扩展的新版本1.2.1,它现在支持在浏览器模式下运行。

0
0 313
文章 Michael Lei · 八月 8, 2022 2m read

医疗行业的互操作性在改善病人护理、降低医疗服务提供者的成本以及为提供者提供更准确的情况方面发挥着重要作用。然而,由于有这么多不同的系统,数据的格式也有很多不同的方式。有许多标准被创造出来以试图解决这个问题,包括HL7v2、HL7v3和CDA,但每一种都有其缺点。

FHIR,即快速医疗互操作性资源,是一种新的医疗数据格式,旨在解决这些问题。它是由国际卫生级七组织(HL7)开发的,该组织还开发了HL7v2、HL7v3和CDA。

今天我们将探讨如何在VS代码中借助IntelliSense和自动完成功能,通过使用FHIR Schema 创建和验证FHIR资源。

第 1 步 :从FHIR 官方网站 https://www.hl7.org/fhir/下载 JSON schema file 文件用来做资源校验

第 2 步: 创建文件夹(在这个例子中,我使用病人文件夹和病人资源),并将提取的fhir.schema.json文件复制到同一文件夹,然后从VS Code中打开文件夹

第 3 步: 通过修改setting.json文件,设置VS代码以识别FHIR模式。
按CTRL+SHIFT+P并输入工作区设置JSON文件

第 4 步: 在同一文件夹中创建一个新文件patient.fhir.json。
按Ctrl+Space,你将通过IntelliSense获得FHIR资源的所有属性

0
0 475
公告 Michael Lei · 五月 2, 2022

本月我们正式发布VS Code ObjectScript扩展的1.8.0版本,它包含以下增强功能和错误修复。

最大的更新是支持服务器端的项目文件,因为很多人会记得Studio。如果你在客户端工作,VS Code已经有很好的项目管理功能。你可以简单地使用一个文件夹作为一个项目,或者使用多个根目录的工作空间。但是如果你在服务器端工作,你可能会喜欢一些更好的工具管理能力,这就是这个功能的意义所在。更多内容,欢迎查阅文档的新项目章节

1.8.0版本的更新日志

  • 增强功能
    • 增加对服务器端项目的支持 (#851)
    • 实现isfs文件夹的重命名和删除 (#923, #922)
    • 支持isfs和导出过滤器的 "映射 "标志,以过滤从其他数据库映射的软件包(#931)

完整的更新日志在这里

如果您已经安装了ObjectScript扩展,VS Code会自动更新。如果您是一个新用户,请从这里开始。 

0
0 138
文章 Michael Lei · 四月 17, 2022 3m read

在IRIS容器里添加VSCode

设置可重复的开发环境的最简单的方法之一是使用容器。我发现在快速迭代时,在我的开发环境容器里托管一个vscode实例是非常方便的。因此,我创建了一个快速的容器脚本,将一个基于浏览器的vscode添加到IRIS容器中。这应该适用于大多数2021.1以上的容器。我的代码库可以在这里找到

带VSCode 且预连接好的InterSystems IRIS 容器

CredValue
User_SYSTEM
PasswordSYS

image

概要

这个项目创建了一个IRIS容器,在同一个IRIS容器中提供了vscode的托管(web-based)版本。这提供了:

  • 同样的容器代码编辑
  • 预连接到容器内的IRIS 实例
  • 管理门户里的链接
  • 自动启动IDE

快速启动

  1. 下载 或者 git clone https://github.com/nickmitchko/Hosting-vscode-in-a-container.git
  2. 在项目根目录下, 运行 docker build . -t vscode-irishealth-ml:latest --no-cache
  3. 执行 docker-compose up
    • 不使用 docker compose? 请看 这里
  4. 浏览 管理门户
  5. 用用户名和密码登陆
  6. 在Favorites 面板里点击 VSCODE 链接 on the favorites pane
  7. 依据提示在VScode里使用相同的用户名/密码 来连接到IRIS 实例
# New folder for project
mkdir vscode-iris
cd vscode-iris

# Clone repo here
git clone https://github.com/nickmitchko/Hosting-vscode-in-a-container.git .

# Build image
docker build . -t vscode-irishealth-ml:latest --no-cache

# Only Run (A) or (B)
#
# (A) Run compose file
docker-compose up
# OR (B) if you want a daemon
docker-compose up -d

添加持久化

如果想要一个持久化IRIS实例, 去掉docker-compose.yml 文件中16-20行里的注释 . 这样就在容器上增加了一个持久化存储的挂载。

    volumes:
    - "./durable/:/durable/"
    environment:
    - ISC_DATA_DIRECTORY=/durable/iconfig

改变基础镜像Base Image

这个镜像是建立在 InterSystems 开发者社区 zpm 镜像上 (看这里). 这些镜像包括了让我们从package repo 安装的zpm命令,只是仅有一个90天的社区版 license。

用于这个builds上的镜像标签image tag:

FROM intersystemsdc/irishealth-ml-community:latest

如果你想改变镜像, 把docker 文件里的第一行改成你想要的镜像标签image tag (可以是一个自定义的IRIS instance 或者 官方支持的). 例如:

FROM containers.intersystems.com/intersystems/irishealth-community:2021.2.0.651.0

无 Docker-Compose

如果你没有用 docker compose, 你仍然可以如下运行容器:

# After building the container
# --after command is required
docker run --name vscode -d \
    --publish 1972:1972 \
    --publish 52773:52773 \
    --publish 51773:51773 \
    --publish 53773:53773 \
    --publish 8080:8080 \
    --publish 8888:8888 \
    vscode-irishealth-ml:latest \
    --after "/bin/bash /install/boot.sh"
0
0 470
文章 Michael Lei · 四月 13, 2022 7m read

image

这篇文章是对我的  iris-globals-graphDB 应用的介绍。
在这篇文章中,我将演示如何在Python Flask Web 框架和PYVIS交互式网络可视化库的帮助下,将图形数据保存和抽取到InterSystems Globals中。

建议

第一步 : 通过使用Python 原生SDK建立与IRIS Globals的链接

 #create and establish connection
  if not self.iris_connection:
         self.iris_connection = irisnative.createConnection("localhost", 1972, "USER", "superuser", "SYS")
                                     
  # Create an iris object
  self.iris_native = irisnative.createIris(self.iris_connection)
  return self.iris_native

 

第二步 : 使用 iris_native.set( ) 功能把数据保存到Globals 里     

#import nodes data from csv file
isdefined = self.iris_native.isDefined("^g1nodes")
if isdefined == 0:
    with open("/opt/irisapp/misc/g1nodes.csv", newline='') as csvfile:

reader = csv.DictReader(csvfile) for row in reader: self.iris_native.set(row["name"], "^g1nodes", row["id"])

#import edges data from csv file isdefined = self.iris_native.isDefined("^g1edges") if isdefined == 0: with open("/opt/irisapp/misc/g1edges.csv", newline='') as csvfile: reader = csv.DictReader(csvfile) counter = 0                 for row in reader: counter = counter + 1 #Save data to globals self.iris_native.set(row["source"]+'-'+row["target"], "^g1edges", counter)  

第三步: 使用iris_native.get() 功能把节点和边缘数据从Globals传递给PYVIS

 #Get nodes data for basic graph    
  def get_g1nodes(self):
        iris = self.get_iris_native()
        leverl1_subscript_iter = iris.iterator("^g1nodes")
        result = []
        # Iterate over all nodes forwards
        for level1_subscript, level1_value in leverl1_subscript_iter:
            #Get data from globals
            val = iris.get("^g1nodes",level1_subscript)
            element = {"id": level1_subscript, "label": val, "shape":"circle"}
            result.append(element)            
        return result

    #Get edges data for basic graph       def get_g1edges(self):         iris = self.get_iris_native()         leverl1_subscript_iter = iris.iterator("^g1edges")         result = []         # Iterate over all nodes forwards         for level1_subscript, level1_value in leverl1_subscript_iter: #Get data from globals             val = iris.get("^g1edges",level1_subscript)             element = {"from": int(val.rpartition('-')[0]), "to": int(val.rpartition('-')[2])}             result.append(element)                     return result

 

Step4: Use PYVIS Javascript to generate graph data

<script type="text/javascript">
    // initialize global variables.
    var edges;
    var nodes;
    var network;
    var container;
    var options, data;
  
    // This method is responsible for drawing the graph, returns the drawn network
    function drawGraph() {
        var container = document.getElementById('mynetwork');
        let node = JSON.parse('{{ nodes | tojson }}');
        let edge = JSON.parse('{{ edges | tojson }}');
     
        // parsing and collecting nodes and edges from the python
        nodes = new vis.DataSet(node);
        edges = new vis.DataSet(edge);

        // adding nodes and edges to the graph         data = {nodes: nodes, edges: edges};

        var options = {           "configure": {                 "enabled": true,                 "filter": [                 "physics","nodes"             ]             },             "nodes": {                 "color": {                   "border": "rgba(233,180,56,1)",                   "background": "rgba(252,175,41,1)",                   "highlight": {                     "border": "rgba(38,137,233,1)",                     "background": "rgba(40,138,255,1)"                   },                   "hover": {                   "border": "rgba(42,127,233,1)",                     "background": "rgba(42,126,255,1)"                 }                 },

                "font": {                   "color": "rgba(255,255,255,1)"                 }               },             "edges": {                 "color": {                     "inherit": true                 },                 "smooth": {                     "enabled": false,                     "type": "continuous"                 }             },             "interaction": {               "dragNodes": true,                 "hideEdgesOnDrag": false,               "hideNodesOnDrag": false,                 "navigationButtons": true,                 "hover": true             },

            "physics": {                 "barnesHut": {                     "avoidOverlap": 0,                   "centralGravity": 0.3,                   "damping": 0.09,                     "gravitationalConstant": -80000,                     "springConstant": 0.001,                     "springLength": 250                 },

                "enabled": true,                 "stabilization": {                     "enabled": true,                     "fit": true,                     "iterations": 1000,                     "onlyDynamicEdges": false,                     "updateInterval": 50                 }             }         }         // if this network requires displaying the configure window,         // put it in its div         options.configure["container"] = document.getElementById("config");         network = new vis.Network(container, data, options);       return network;     }     drawGraph(); </script>

 

第五步: 从app.py 主文件调用上面的代码

#Mian route. (index)
@app.route("/")
def index():
    #Establish connection and import data to globals
    irisglobal = IRISGLOBAL()
    irisglobal.import_g1_nodes_edges()
    irisglobal.import_g2_nodes_edges()

    #getting nodes data from globals     nodes = irisglobal.get_g1nodes()     #getting edges data from globals     edges = irisglobal.get_g1edges()

    #To display graph with configuration     pyvis = True     return render_template('index.html', nodes = nodes,edges=edges,pyvis=pyvis)    

下面是关于此项目的 介绍视频:

<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="315" scrolling="no" src="//player.bilibili.com/player.html?aid=256588464&bvid=BV1LY411w7MU&cid=718938724&page=1" width="560"></iframe>欢迎大家来我们的 Bilibili主页观看更多视频!


谢谢!

0
0 294
公告 Jeff Liu · 三月 30, 2022

HI 开发者们,

我们在bilibili 发布了新的视频!

<iframe src="//player.bilibili.com/player.html?aid=637281555&bvid=BV1cb4y1p7RE&cid=550213579&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>

看看VS Code的InterSystems ObjectScript的调试器如何帮助你浏览和检查代码。了解如何为调试类方法和production组件编写启动配置,并获得VS Code调试器界面的概述--包括变量部分、观察窗格和调试控制台。

请欣赏并继续关注!

1
0 206