文章 Nicky Zhu · 1 小时 前 7m read

让 AI 接手数据集成:几分钟里跑起来

一句话速览:登记数据源、选择目标,再让 LLM 设计数据集成流程。一条命令启动演示环境,再运行一条命令,就能端到端复现完整的数据管道。

git clone --recurse-submodules https://github.com/zlnick/DataPipelineDemo.git
cd DataPipelineDemo
bash tools/setup.sh && python3 tools/e2e_ui_flow.py

↑ 一次干净克隆环境中的实测:、验证通过,数据已写入目标 FHIR 仓库。


这是什么

这是一个运行在 InterSystems IRIS for Health 上的完整演示:由数据源出发,自动生成并运行互操作性数据管道,其中的关键决策由 AI 完成。

  • 数据源(2 种):FHIR 接口、SQL 表
  • 转换目标(3 种):数据库表、SOAP 服务、FHIR 仓库
  • 支持多种源与目标组合,也支持在同一个 Production 中运行多条数据管道
  • 提供中英双语界面:默认中文,英文界面位于 /en

 

一套 IRIS 实例同时承担多个角色:FHIR 服务器(包含相互独立的源与目标两个仓库)、互操作性引擎(Production)、SQL 数据库,以及平台自身的元数据存储。

0
0 3
文章 Nicky Zhu · 十月 10 9m read

将人工智能代理连接到数据库固然有用,但这立刻引发了另一个问题:应该允许该代理读取哪些内容?

在这个项目中,我希望在应用程序代码中做出这一决定。代理可以使用几个过滤条件搜索患者记录,检查一个已批准的全局变量,并检索有关 IRIS 命名空间的基本信息。它不能提交自己的 SQL 查询,也不能选择其他命名空间。


这个项目是什么?

我为 InterSystems社区奖励计划“从构想到应用”(第二轮)开发了MCP 数据暴露工具包,以响应MCP 数据暴露工具包的构想(DPI-I-985)。 我的贡献是一个可运行的 ObjectScript 示例,涵盖了 SQL、全局变量和命名空间监控。

源代码已在GitHub 上发布。本文将演示该示例的运行过程,并深入解析其背后的代码。

示例公开的内容

我选择了合成医疗记录,因为它们既提供了有用的搜索条件,又避免了将真实的患者信息存储在存储库中。该项目从Kaggle 上由 dnation 发布的“合成医疗患者记录数据集”中导入了 500 条记录。持久化类 MCPData.Data.Patient 用于存储这些记录。

0
0 9
文章 Nicky Zhu · 十月 8 8m read

在 4.0.0 发布一周后,SQL DATA LENS 4.01 于 2026 年 8 月 30 日正式发布——这是一次重大版本更新,而非补丁更新。 其78项变更中的大部分都围绕一个主题:如何建立、保护和标记与IRIS或Caché的连接。本文将带您了解对于日常使用InterSystems数据库的用户而言最重要的部分,首先从我被问及最多的那个问题开始。

问题在于:对于 InterSystems JDBC 客户端而言,TLS 配置从来都不是“只需勾选一个复选框”就能解决的

如果您曾使用 TLS 保护过 IRIS 超级服务器,然后尝试让 Java 客户端与其通信,您一定深有体会。在客户端,您需要

  • 一个SSL 配置文件(即 InterSystems JDBC 驱动程序读取的 SSLDefs.ini- 风格的属性文件),
  • 一个使用 keytool 构建的信任库,其中包含服务器或 CA 证书,
  • 主机名验证必须与证书 SAN 字段中的 条目完全匹配,
  • 以及重启客户端以验证上述操作是否生效。

社区中有关此主题的优秀文章不少——Mauro Aguirre 针对 ODBC/JDBC 客户端的分步指南以及Eduard Lebedyuk 的 Tableau 操作指南都值得一读。但这些文章之所以需要存在,且篇幅长达 6 到 13 分钟这一事实,本身就说明了一些问题。

0
0 9
文章 Nicky Zhu · 九月 30 4m read
大家好,这是关于 InterSystems IRIS 中镜像(Mirroring)和分片(Sharding)技术的三篇系列文章中的第一篇。第一部分将介绍如何启动三个容器并加入镜像。第二部分将介绍如何正确读取仲裁器(Arbiter)状态、一夜之间自动发生的故障转移,以及因我过于心急而导致的数据库“孤立”问题。第三部分将深入探讨分片技术,其中包含一个曾让我对整个配置产生怀疑的查询结果,直到我弄清楚它为何实际上是正确的。
本系列中的所有内容均在 Docker 上构建并测试,每张截图均直接来自该运行环境的管理门户。

步骤 1:配置三个容器

镜像功能需要三个角色:主节点(Primary)、备用节点(Backup)和仲裁者(Arbiter)——当两者对对方是否仍处于活动状态存在分歧时,仲裁者将打破平局。我将这三个角色作为独立的 Docker 容器在同一网络上运行,这样既保证了整个实验环境的可重复性,又便于在出现问题时快速拆卸环境。
在运行任何内容之前,您需要实际的 IRIS 镜像和一个许可证密钥文件。该镜像来自 InterSystems 容器注册表,因此请先使用您自己的凭据登录该注册表:
docker login -u="your-username" -p="your-token" containers.intersystems.com

然后拉取镜像:

docker pull containers.intersystems.com/intersystems/irishealth:2025.3
0
0 13
文章 Nicky Zhu · 九月 17 6m read


                                                                                                              ____( o)>
                                                                                                              \ <_. )
                                                                                                                 `---'   
.                     某个类突然无法被找到。 
                      尽管你知道数据确实存在,但查询却未返回任何行。 
.                     ObjectScript 方法失败,却没有明显的原因。 
.                     应用程序在某个环境中能成功连接,但在另一个环境中却无法连接。
.                     

0
0 28
文章 Nicky Zhu · 九月 16 10m read

SQL DATA LENS 4.02 于 2026 年 9 月 4 日发布。在其各项更新中,有一项我特别想重点提及,因为这是我多年来一直期待却从未在其他地方找到的功能:SQL DATA LENS 现在可以直接在“Global Browser”中打开一个 .gof 文件——即 InterSystems 的 %GOF 块格式global导出文件——直接在“Global Browser”中,因此您可以在收到导出文件后立即浏览其内容,而无需先将其导入任何地方。

这是一项全新的功能,而块格式最初是作为 IRIS 实例之间的内部传输格式设计的,从未被设想为第三方工具可读取的格式——因此我们是通过研究 IRIS 的写入内容来理解它的,而非基于任何规范。 这正是我撰写此文的原因:希望您能用自己的导出文件试用该功能,并告诉我们您的使用体验。下文将介绍该功能的工作原理、我认为其有用的原因、当前的局限性,以及哪些反馈对我们最有帮助。

问题在于:.gof 文件必须先导入才能查看

如果你长期使用 IRIS 或 Caché,.gof 文件就会开始堆积如山。 管理门户会生成这些文件(系统资源管理器 ▸ 全局变量 ▸ 导出,“块格式” | System Explorer ▸ Globals ▸ Export, "block format" ),^%GOF 会生成这些文件,##class(%Library.Global).Export(...)

0
0 33
文章 Nicky Zhu · 八月 29 3m read

IRIS数据建模的决策框架。

关于选用哪种模型的决策涉及多方面因素。 我建议分别对每个维度进行评分,然后将结果相乘。 根据您偏好的评分方式,得分最高或最低的模型胜出。 我看到了这些维度,但具体方面可能会使列表进一步扩展。

  • 开发人员在 SQL、面向对象和Globals方面的技能
  • 维护人员和运维人员在 SQL、面向对象和Globals方面的技能
  • 与 SQL、面向对象、Globals相关的数据文化
    • 我曾遇到过完全拒绝使用SQL的客户
  • 开发和测试所需的时间
  • 需存储在SQL、面向对象和Globals中的结构复杂度
  • 访问速度
  • 存储消耗
  • 数据类型和质量检查
  • 对变更和增强的灵活性…… 
  • 更多

SQL的技术维度

  • 若仅包含简单列,生成 CREATE TABLE 语句的速度会很快

    • 但添加外键或引用其他表可能会带来挑战
  • 访问速度仅对大型表重要,且受以下因素影响

  • 存储空间消耗

    • 您可以将其完全交给代码生成器处理,几乎无需干预
    • 在后台,每张表都对应一个 Object 类
    • 以及一组可供使用的Globals
  • 要提高访问速度,需要巧妙地建立索引

  • 您可以对标准数据类型进行全面检查

  • 灵活性

    • 仅需添加一列便十分简单
    • 更复杂的更改可能会让人头疼不已

对象的技术维度

  • 利用现有的工具,创建一个对象类是一件轻而易举的事。

0
0 49
文章 Nicky Zhu · 八月 19 17m read

处理遗留代码时的差异与注意事项

刚开始接触 ObjectScript 时,我编写的大部分代码都遵循了 InterSystems 的现代编程模式。我使用类、方法、REST 服务、互操作性生产、JSON 对象以及 %Status 值。

与此同时,我负责维护的生产系统中,很大一部分代码采用的编写风格却截然不同。

该系统使用了例程、标签、global、缩写命令、“点-do”语法、共享局部变量以及错误处理模式——这些在基于类的 ObjectScript 普及之前就已经存在了。

起初,我曾以为这仅仅是旧语法与新语法的区别。随着时间的推移,我意识到最大的差异并非表面上的。传统的MUMPS风格代码与现代ObjectScript在变量作用域、执行层级、数据流和错误处理方面往往基于不同的假设。这种区别至关重要,因为旧代码很容易被误读。

某个例程看似未接收任何参数,却依赖于调用者创建的多个变量;某个标签在某处表现得像一个过程,在另一处却表现得像一个函数;一个点块(dot block)虽然会创建另一个执行层级,却可能看起来像缩进;一段代码在移入类后虽然能编译通过,但在运行时却可能表现得截然不同。

代码看起来依然很熟悉。语言依然是 ObjectScript。然而,它可能已经发生了变化。

本文介绍了我在处理遗留代码并将其与更现代的 ObjectScript 应用程序集成时所遇到的一些最重要的差异。

1.

0
0 60
文章 Nicky Zhu · 七月 15 4m read

项目链接

概述

FHIR 患者快照代理(FHIR Patient Snapshot Agent)是一款专为 InterSystems AI 代理和 FHIR 编程竞赛开发的小型开源应用程序。

该项目实现了建议的“智能患者摘要生成器”构想:它检索所选患者的结构化 FHIR 资源,并生成一份简明扼要、针对特定角色的患者摘要。

其目的并非进行诊断或推荐治疗方案。该代理仅作为摘要生成助手,所有生成的内容都必须与源FHIR数据进行核对验证。

InterSystems IRIS for Health 的应用方式

该应用程序使用 InterSystems IRIS for Health 作为 FHIR 互操作性层。

在本地部署环境中,IRIS for Health 提供了一个 FHIR R4 API。Python 应用程序通过查询该 API 来获取与患者相关的资源,包括:

  • 患者
  • 病情
  • 用药请求
  • 过敏与不耐受
  • 观察
  • 就诊
  • 护理计划

该 Python 应用程序不会直接读取本地临床文件。

0
0 84
文章 Nicky Zhu · 七月 15 5m read

在我的第一篇文章中,我介绍了 FHIR 患者快照代理的基础版本:这是一个基于 Streamlit 和 Python 的应用程序,它从 InterSystems IRIS for Health 中检索 FHIR 资源,并利用大型语言模型(LLM)生成简明扼要的患者摘要。

本文作为后续文章,将介绍我是如何通过添加两项针对 InterSystems 的功能来扩展该项目的:

  • 源上下文向量搜索
  • 用于 IRIS 兼容审查的嵌入式 Python 组件

目标是让该项目作为临床摘要原型更具实用性,同时保持设计足够精简,以便于理解和复现。

项目回顾

FHIR 患者快照代理(FHIR Patient Snapshot Agent)是一款基于人工智能的 FHIR 患者数据摘要工具。

该应用程序可检索所选患者的结构化资源:

  • 患者
  • 病情
  • 用药请求
  • 过敏与不耐受
  • 观察
  • 就诊
  • 护理计划

Python 层将这些资源整合为一个紧凑的患者背景。用户随后可以生成以下任一内容:

  • 确定性摘要,或
  • 由大型语言模型(LLM)生成的针对特定角色的摘要

该 LLM 集成通过兼容 OpenAI 的聊天补全 API 使用 Nebius Token Factory。演示中使用的模型为:

meta-llama/Llama-3.3-70B-Instruct

该项目为开源项目:

0
0 66
文章 Nicky Zhu · 七月 1 1m read

我很高兴与大家分享FHIR Agent Studio 的演示视频,该视频现已在 YouTube 上发布。

FHIR Agent Studio 演示视频

https://www.youtube.com/watch?v=vktfq_kvNnk

FHIR Agent Studio 将 AI Agent与 FHIR、InterSystems IRIS、Vector Search 以及大型语言模型相结合,向开发者展示如何探索、构建和测试由Agent驱动的医疗保健工作流。

您还可以在此处查看更多信息:

介绍文章:https://community.intersystems.com/post/introducing-fhir-agent-studio-ai-agents-fhir-intersystems-iris

GitHub 代码库:https://github.com/SeanConnelly/ai-studio-for-fhir

Open Exchange 页面:https://openexchange.intersystems.com/package/FHIR-Agent-Studio

0
0 64
公告 Nicky Zhu · 七月 1

我很高兴地告诉大家FHIR Agent Studio现已在 InterSystems Developer Cloud 上作为在线托管演示运行—— 无需安装,无需配置,只需在浏览器中打开即可。

FHIR Agent Studio 是一个开发者门户,用于在单一的 InterSystems IRIS for Health 后端上 构建、运行和检查面向 FHIR 工作流的 AI代理。每个 代理都是一个小型临床工作流,您可以从左到右阅读其流程:

Trigger -> Evidence (FHIR / SQL / Vector Search) -> Agent (LLM) -> Action (draft FHIR) -> Trace

该平台随附十二个可运行的代理,基于一个包含约 1,000 名患者和 20,000 多个资源的合成 FHIR 存储库,此外还提供一个面向临床医生的应用程序和一个面向患者的手机 应用程序,均运行在同一后端上。每次运行的每个步骤均可追溯。

立即试用(无需登录)

应用程序界面已开放——只需点击即可探索:

 

  Link
引导式演示——从这里开始,快速了解全部十二个智能助手 https://fhir-agent-studio.sandbox.developer.intersystems.com/clinical/#/demo
0
0 75
文章 Nicky Zhu · 六月 29 8m read

人工智能将改变医疗保健行业,但前提是临床医生能够信任它,而开发人员 在构建它时无需每次都从头开始重新设计基础架构。 FHIR Agent Studio 正是我 为实现这两点所做的尝试:它是一个平台,可以利用可重用的构建 模块为 FHIR 工作流构建 AI 代理,在真实的 InterSystems IRIS for Health 后端上运行它们,并精确 检查每个代理在每个步骤中执行了哪些操作。

这是我参加 InterSystems FHIR AI Agent 竞赛的参赛作品,它附带了 十二个可运行的代理,这些代理运行在一个包含约 1,000 名患者和 20,000 个资源的合成 FHIR 存储库上。 我的目标是打造一个“工作室”而非单一的演示程序:在这里,您可以 设计、运行和检查多个代理,进而构建自己的代理。所有操作均在单个 容器中运行,仅需一条命令,且无需 API 密钥。

克隆该仓库并运行 docker compose up --build。然后打开引导式演示,运行其中的任意一个代理。 每个步骤都可供您详细查看。

从引导式演示开始

如果你只能做一件事,那就打开引导式演示。它带你游览全部十二个代理, 每个代理都配有通俗易懂的说明、一个直接跳转到相应界面的“试一试”链接, 以及关于注意事项的提示。即使你对该项目一无所知, 也能在几分钟内探索其全部内容。

The guided demo: all twelve agents, each with a description and a Try it link

0
0 146
文章 Nicky Zhu · 六月 17 8m read

在上一篇文章中,我们探讨了 IRIS 中单元测试的基础知识以及将其应用于 REST API 的方法。我们甚至还了解了如何在最终确定网络配置和身份验证之前测试逻辑,从而使我们能够专注于测试 API 内容。

今天,我们将在此基础上使用另一个工具来提升我们的单元测试策略:%Populate。

乍一看,%Populate类似乎非常简单。你可以创建一个同时扩展了 %Persistent和 %Populate的类,并继承一个用于生成随机记录的 方法。该工具可识别某些字段名称(如 "Name"、"SSN" 和 "Phone"),并应用专门的逻辑来确保数据的真实性。如果某个字段名称没有被识别为特殊字段名称,就会按照其指定的数据类型填充随机值。

假设我们开发了这样一个具有以下属性的类,用来跟踪商店中一些基本的客户信息(我们的类还扩展了 ,这在后面会派上用场):

Class User.CustomerList Extends (%Persistent, %Populate, %JSON.Adaptor)
{
    Property Name As %String;
    Property DOB As %Date;
    Property Age As %Numeric(SCALE = 0);
    Property IsMember As %Boolean;
    Property MemberID As %String(POPSPEC = ".GenID()");
}
0
0 166
文章 Nicky Zhu · 六月 10 5m read

Intersystems_pyprod 是InterSystems Python Productions 的简称,它是一个 Python 库,使开发人员能够完全使用 Python 构建这些互操作性组件。该库设计灵活,支持混合方法:您可以将基于 Python 的新组件与现有的基于 ObjectScript 的组件无缝地混合在一起,并充分利用已建立的 IRIS 基础架构。这些 Python 组件一旦定义,就可以像其他组件一样进行管理;可以使用 IRIS 生产配置页面添加、配置和连接这些组件。


快速了解 InterSystems IRIS 生产系统

生产的关键要素

图片来自Learning Services培训材料

IRIS 生产系统通常从外部接口接收数据,通过协调的步骤进行处理,并将其传送到目的地。当信息在系统中移动时,它们会被自动持久化,从而通过 IRIS 的可视化跟踪和日志工具对整个流程进行全面跟踪。该架构依赖于某些关键要素:

  1. 业务主机:这些是核心构件--服务、流程和操作--它们在彼此间传递可持久化的信息。
  2. 适配器:入站和出站适配器管理与外部世界的交互,处理接收和发送数据所需的特定协议。
  3. 回调:引擎使用特定的回调方法在主机之间同步或异步地传递消息。这些回调方法遵循严格的签名,并返回一个 Status 对象,以确保执行的完整性。
0
0 221
文章 Nicky Zhu · 六月 9 5m read

在 ObjectScript 代码中,ClassMethods 的使用似乎很普遍。我希望我自己的经历不具有代表性,但我打赌它们确实具有代表性。请原谅我泄露了本文的结尾,但简而言之:不要使用它们。除非你能提出令人信服的理由证明你必须这样做,否则就永远不要使用它们1。

什么是ClassMethod?在 ObjectScript 类中,您可以通过两种不同的方式定义方法:在 Method 中,您必须实例化类的实例才能调用方法;而在 ClassMethod 中,您可以调用方法而无需实例化类。当然,在 ClassMethod 中,你无法访问对象的任何属性(因为没有对象),但你可以访问 globals(毕竟它们是全局的)和 Parameters(即类常量)。

0
0 87
文章 Nicky Zhu · 五月 29 2m read

今天,我发布了一个新的Open Exchange 软件包,用于直接在 IRIS 中生成合成数据。

当你想制作一个演示应用程序时,找到合适的数据集是一个令人沮丧的过程。也许数据集并不那么重要,但您仍然希望它看起来有点真实,并有几个链接表,可以直接在 IRIS 中使用 -> 的隐式连接。也许您只是想让链接表可以很容易地安装到 IPM 中,用于基准查询,那么这种数据集生成方式就再好不过了。

我选择使用嵌入式 Python 创建数据集,这些数据集可通过自定义配置文件进行配置。这些数据集直接用一个 IRIS 类方法生成,并可使用乘数进行缩放,以创建任意大小的数据集,而无需测量配置。

目前我有四个数据集:
- 金融服务(如银行卡、账户、交易)
- 零售(商店、产品、用户、库存)
- 供应链(产品、销售订单、库存移动)
- 主题公园管理(公园、区域、游乐设施、事故)

我不是这些领域的专家,所以我怀疑它们是否超级准确,而且数据生成使用了 faker 等 python 库,统计加权生成使用了 numpy,所以感觉有点人工合成。

老实说,作为一个我无法投入大量时间的副业项目,这个项目的成功离不开人工智能。我在设计数据集和生成创建数据集的代码时广泛使用了人工智能。我监督、测试了个人使用的案例,并积极参与了项目设计,但代码都是人工智能生成的,我没有仔细审查过数据集的生成过程。

0
0 68
文章 Nicky Zhu · 五月 26 3m read

高级工程的定义不在于代码量的多少,而在于策略性地避免代码量。在复杂的集成环境中,倾向于利用通用库来满足每一个细分需求会带来不必要的开销。要实现真正的架构成熟,就必须致力于 "最小化工具"--优先考虑有弹性、经过实战检验的系统实用程序,而不是自定义逻辑。本评估将检查我们的 PGP 加密/解密流水线,以展示如何从应用级库转向操作系统本地授权,从而提高系统的耐用性。

现状:重量级实现

我们当前的 MPHP.HS.PGPUtil 类是一种高摩擦设计。现有的 InterSystems IRIS 业务流程虽然功能强大,但依赖性很强。通过桥接嵌入式 Python 来使用 pgpy 库,我们引入了一个 "重型 "堆栈,需要 Python 运行时、第三方库管理和特定的加密二进制文件。

0
0 46
文章 Nicky Zhu · 五月 25 6m read

经常有客户就内存大小问题与我联系,因为他们会收到 "可用内存 "低于阈值的警报,或者发现 "可用内存 "突然减少。出现问题了吗?他们的应用程序会不会因为运行系统和应用程序进程的内存不足而停止工作?答案几乎总是否定的,没有什么好担心的。但这个简单的答案通常是不够的。请看下图。它显示的是 vmstat 中 free 指标的输出。还有其他方法可以显示系统的可用内存,例如 free -m 命令。有时,_free 内存_会随着时间的推移而逐渐消失。然而,下图是一个极端的例子,但它很好地说明了发生了什么。 image 如你所见,在凌晨 2 点左右,一些内存被释放,然后突然下降到接近零。该系统正在 InterSystems IRIS 数据库上运行 IntelliCare EHR 应用程序。vmstat "信息来自一个收集 "vmstat"、"iostat "和许多其他系统指标的"^SystemPerformance "HTML文件。这个系统还发生了什么?现在是半夜,医院里应该没什么事。让我们看看数据库卷的 iostat 情况。 在_free memory_下降的同时,出现了一阵读取。报告的 free memory 下降与数据库磁盘的 中显示的大量块大小读取(2048 KB 请求大小)的峰值一致。这很可能是备份过程或文件复制操作

0
0 145
文章 Nicky Zhu · 五月 22 3m read

从 Oracle、MSSQL 或其他纯关系型数据库系统迁移到多模型 InterSystems IRIS 是一项战略决策,需要认真规划和执行。虽然这种过渡具有显著的优势,包括增强性能、可扩展性和对现代架构的支持,但它也伴随着挑战。在本文中,我将重点介绍与编码相关的一些注意事项,以确保成功迁移。与结构和数据的实际迁移相关的所有事项都不在本文讨论范围之内。


首先,当你考虑迁移到不同的数据库系统时,你需要了解你的业务逻辑,无论是在应用程序(应用服务器)还是数据库服务器端。基本上,你需要重写的 SQL 语句在哪里?

0
0 66
文章 Nicky Zhu · 五月 12 10m read

RabbitMQ 是一个消息代理,它允许生产者(发送数据消息的一方)和消费者(接收数据消息的一方)建立异步、实时且高性能的海量数据流。RabbitMQ 支持 AMQP(高级消息队列协议),这是一种开放标准的应用层协议。

采用 RabbitMQ 的主要原因包括以下几点:

  • 您可以使用异步方法来提高应用程序的性能。
  • 它通过数据消息中介,让您能够解耦并减少服务、微服务和应用程序之间的依赖关系,这意味着交换数据的生产者和消费者无需互相了解。
  • 它允许在利用响应队列之后,交付(包含结果的)已发送数据的长时间运行处理。
  • 它帮助您从单体架构迁移到微服务架构,其中微服务通过 Rabbit 以解耦和异步的方式交换数据。
  • 它通过使消息能够被存储和转发,提供了可靠性和弹性。一条消息可以被投递多次,直到被处理为止。
  • 消息排队是扩展应用程序的关键。随着工作负载的增加,您只需添加更多的工作进程(worker)来更快地处理队列。
  • 它与数据流应用程序配合良好。
  • 它对物联网(IoT)应用程序有益。
  • 它是机器人(Bots)通信的必备工具。

RabbitMQ 基础概念

我们将利用温度监测器作为案例来详述 RabbitMQ 的概念:

  • Producer(生产者):发送消息的软件程序。
  • Exchange(交换机):接收来自生产者的消息,并将其路由到零个或多个队列。
  • Queue(队列):支持小型和大型二进制消息的消息存储区/缓冲区。
0
0 99
文章 Nicky Zhu · 四月 10 2m read

处理文件通常很简单:打开文件,读取并处理。这种方法非常有效,直到文件碰巧是 Excel 文件。

常见假设

起初,Excel 文件(.xlsx)看起来就像另一个数据文件,行、列和值。因此,我们很自然地认为它可以像 .txt 或 .csv 文件一样被读取。但问题就出在这里。

Excel 文件为何表现不同

关键区别在于数据的存储方式:

-> .txt / .csv - 纯文本,逐行存储。

-> .xlsx - 压缩、结构化格式(非纯文本)

excel 文件实际上不是一个简单的可读行流。从内部看,它是一个包含结构化数据的打包文件,标准文件读取命令无法解释这些数据。

如果把它当作文本文件处理,会发生什么情况?

  • 执行过程中出现错误
  • 输出看起来无法阅读

重要事项 --> 这不是限制,而是工具和文件格式不匹配 。


实用的处理方法

与其只使用基于文本的方法,还有更好的选择、

  • 转换为 CSV
  • 嵌入 Python (pandas 或 openpyxl 等库)
  • IRIS 互操作性工具

如果有人曾在 IRIS 中处理过 Excel 文件,或有其他行之有效的方法,请随时分享。)

下面提到几个例子。

0
0 368
文章 Nicky Zhu · 四月 9 1m read

简介

FHIR(快速医疗互操作资源)是存储和交换临床数据的现代标准。但是,一旦您的数据存储在 FHIR 服务器中,如何才能真正浏览这些数据呢?FHIR 数据以 JSON 格式存储,虽然功能强大,但直接读取并不实用。我希望有一种工具,可以让您点击病人,以简洁、可读的格式查看他们的病情、用药、化验结果等。于是,我创建了FHIR 患者查看器(FHIR Patient Viewer)。

如何运行

该应用完全在 Docker 中运行,并直接连接 InterSystems IRIS for Health FHIR 服务器。启动时,它会自动将 115 个合成患者载入 IRIS,无需手动设置。

  • 浏览患者列表
  • 点击任何患者,查看其所有临床记录

  • 逐字段展开每条记录

  • 随时查看底层原始 JSON 文件


     

数据

它预装了由Synthea生成的 115 个合成患者数据


Open Exchange 上有完整的源代码和设置说明:
https://openexchange.intersystems.com/package/FHIR-Patient-Viewer-2

欢迎反馈!

0
0 337
文章 Nicky Zhu · 四月 1 7m read

您熟悉 SQL 数据库,但不熟悉 IRIS 吗? 请继续阅读...

大约一年前,我加入了 InterSystems,IRIS 就这样进入了我的视线。 我使用数据库已经有 40 多年了,其中大部分时间都是为数据库供应商工作,我以为 IRIS 与我所知道的其他数据库大致相同。 然而,我惊讶地发现,IRIS 在很多方面都与其他数据库截然不同,而且往往要好得多。 这是我在 Dev Community 上发表的第一篇文章,我将为已经熟悉 Oracle、SQL Server、Snowflake、PostgeSQL 等其他数据库的人提供 IRIS 的高级概述。 希望我的介绍能让您更清楚、更简单,并节省您的入门时间。

首先,IRIS 支持 ANSI 标准 SQL 命令和语法。它有表格、列、数据类型、存储过程、函数......所有关系型的东西。 你还可以使用 ODBC、JDBC 和 DBeaver 或任何你喜欢的数据库浏览器。 因此,是的,您在其他数据库中知道和做的大多数事情都可以在 IRIS 上正常运行。 耶!

但我提到的那些不同之处又是怎么回事呢? 好了,系好安全带:

多模型(Multi-Model):IRIS 是一个关系数据库,但同时也是一个面向对象的数据库,还是文档存储,支持向量和立方体/MDX,以及.你知道我要说什么。

0
0 235
文章 Nicky Zhu · 三月 26 3m read

已包含在 SystemPerformance 中

SystemPerformance 已内置 NFS 磁盘命令(包括 nfsiostat),但默认处于禁用状态。通过以下命令启用:

$$Enablenfs^SystemPerformance()

启用后,系统将添加以下 NFS 命令(以 Linux 为例):

  • /usr/sbin/nfsstat -cn
  • /usr/sbin/nfsiostat [间隔] [次数]

请确保这些命令已安装且可通过操作系统运行

如需重新禁用,可执行:


向 SystemPerformance 添加通用命令

添加任意操作系统工具时,会在 下创建一个"用户"命令。

示例:

%SYS>set ^IRIS.SystemPerformance("cmds","user",$i(^IRIS.SystemPerformance("cmds","user")))=$lb("nfsiostat","/usr/sbin/nfsiostat ","间隔"," ","次数"," > ")

操作建议:

添加前建议先查看现有命令结构,选择合适的配置文件名称:


为 SystemPerformance 添加带时间戳的

通过脚本可简化实现流程。

包装脚本

保存为 /usr/local/bin/nfsiostat_ts.sh:

#!/bin/bash
# 用法:nfsiostat_ts.sh <间隔> <次数>
INTERVAL=${1:-5}
COUNT=${2:-12}

nfsiostat "$INTERVAL" "$COUNT" | awk '{ print strftime("%Y-%m-%d %H:%M:%S"), $0; fflush() }'
0
0 77
文章 Nicky Zhu · 三月 20 10m read

陷入困境

直到今年年初,我几乎没怎么做过编程工作——我已经厌倦了它。

在担任多年一线软件工程师和数据科学家后,我在2015年左右陷入了职业倦怠。我转而从事以“外部创新”为主的业务拓展角色,并于2019年加入InterSystems担任产品经理。我怀念编程的创造性,但并不怀念其中的枯燥乏味。无休止的样板代码编写、调试和上下文切换让我创意枯竭。就像电影《好好先生》(Yes Man)中金·凯瑞饰演的角色一样,我发现自己对新项目总是说“不”——以至于我换了职业!

然后,AI编程助手出现了。而我,成了对机器人说“好”的“好好先生”。

第一幕:狂热(“对一切都说好!”)

当我刚开始使用AI编程助手(先是Windsurf,然后是Cline,接着是Roo Code,现在是Claude Code,还尝试过opencode)时,感觉就像变魔术一样。自然语言 → 可运行的代码。我对每个建议、每个重构、几乎每个疯狂的想法都说“好”。

我第一个主要的AI辅助项目是几个月前启动的一个内部项目——为IRIS开发的一系列Python脚本和管道。我兴奋不已,让机器人尽情发挥: “添加这个功能!”——好!“重构那个模块!”——好!“让它可配置!”——好!“添加更多集成!”——好!

创意的能量回来了。代码如泉涌。我又感到自己高效了起来。

然后,我的实习生——一名软件工程专业的学生——查看了代码库。

他并不满意。

0
0 331
文章 Nicky Zhu · 三月 12 2m read

数据库表中索引的力量

在使用数据库时,大多数开发人员都了解索引的概念以及使用索引的原因:加快数据检索速度。但是,索引的真正影响往往只有在比较有索引和没有索引的情况时才会显现出来。

你知道没有索引会发生什么吗?
试想一个有三列的表:姓名、年龄和手机号码。


现在,考虑一下这个查询:

如果年龄列没有索引,数据库引擎会

  • 检查 WHERE 条件字段是否有索引。
  • 如果没有,它将扫描整个表(全表扫描)。
  • 对于每一行,它会检查年龄值并返回匹配结果。

这意味着引擎会遍历整个数据结构,这对于大型表来说非常耗时。

索引会发生什么情况?
现在,如果年龄列有索引,流程就会发生巨大变化:

  • 引擎会直接进入索引结构。
  • 它会找到 Age = 26 的节点。
  • 索引指向主表中相应的记录 ID。
  • 结果几乎是瞬间获取的。

这就是为什么索引是如此强大的优化工具。

现实生活中的一课
最近,我们遇到了一个有趣的情况,凸显了索引的重要性。
我们的表有 5 条记录,而年龄列是有索引的。然后,我们错误地从索引结构(而不是主表)中删除了两个条目。这两个条目对应的是 ID X001 和 X005,它们的年龄都是 26 岁。


当我们运行
SELECT ID, Age, EmpId, Mobile, NameFROM Company.Employee WHERE Age = 26
我们预计会有 3 条记录(因为主表中仍有这些记录),但只出现了 2 条记录。

为什么呢?

0
0 202
文章 Nicky Zhu · 三月 10 1m read

InterSystems 常见问题

使用 TCP 适配器的业务主机保持连接和池大小的默认设置如下:

StayConnected = -1(不超时)
PoolSize = 1

如果网络问题导致与业务主机的连接丢失,生产端将无法检测到这一情况,也不会接受新的连接。 在这种情况下,事件日志中不会记录任何事件。 如果将 StayConnected 设置为默认值(-1),连接将不会超时,您需要重启业务主机后才能接受新的连接。 我们建议将 StayConnected 设置为大于或等于 0 的值,以避免出现这种情况。

例如,如果将其设置为 300(秒),TCP 业务主机在 300 秒或更长时间内没有收到任何新信息,就会自动断开连接并重新连接。

对于繁忙的系统,通常会将 StayConnected(保持连接)值设为一个较小的值,如 5 秒。

0
0 186
文章 Nicky Zhu · 三月 5 2m read

Embeddedpy-bridge:嵌入式 Python 工具包

概述

嵌入式 Python改变了 InterSystems IRIS 的游戏规则,可直接在数据库中访问庞大的 Python 生态系统。但是,在 ObjectScript 和 Python 之间架起桥梁有时会让人感觉像是在两个不同的世界之间转换。

为了实现这种无缝过渡,请使用embeddedpy-bridge。

该软件包是一个以开发人员为中心的实用工具包,旨在为嵌入式 Python 提供高级 ObjectScript 封装、熟悉的语法和强大的错误处理功能。它允许开发人员使用他们已经熟悉的本地 IRIS 模式与 Python 数据结构交互。

挑战

虽然 %SYS.Python 库功能强大,但开发人员经常面临一些障碍:

  1. 处理代理:使用原始代理浏览 Python 列表和字典对于 ObjectScript 来说并不 "原生"。
  2. 迭代:标准 ObjectScript While 循环无法与 Python 迭代器进行本地 "对话"。
  3. 命名空间管理:确保 Python 实用程序在整个系统中可用。

解决方案:embeddedpy-bridge

我的目标是创建一个 "桥梁",让 Python 感觉像是 ObjectScript 中的一等公民。

主要功能

  • py 前缀约定:%ZPython.Utils
0
0 528