Aziz Cotrim · 22 hr ago go to post

Ótimo artigo! Trabalho com Ensemble/Interoperability e a integração com Grafana me chamou atenção, parece uma abordagem bem prática para monitorar fluxos de integração em tempo real. Vou explorar isso no nosso ambiente.

Great article! It clearly highlights the practical advantages of using VS Code over older tools, especially with customization and AI integration. I believe this is a really valuable learning resource for developers who are just starting out, as it shows simple but effective ways to improve productivity and better understand complex codebases.

The compile step is what's breaking this, not the export/import itself. When you compile a class in IRIS, embedded SQL gets validated against the schema in the current namespace, that's why classes referencing dropped tables fail to compile in TEST, even though the same classes have presumably been running fine in LIVE (their existing object code was never re-validated after the tables disappeared).

Do $SYSTEM.OBJ.Import("production.xml", "-c")

This loads the classes without triggering the compile/schema-validation step, so the missing tables won't block the import. Just make sure your export actually contains compiled artifacts (OBJ), not just source, exporting only .CLS/source and skipping compile on import will leave you with uncompiled, unusable classes.

One thing to flag: this only avoids the compile-time check. If any business process actually executes those specific queries at runtime, they'll still fail, you're just deferring validation, not removing the problem. Worth confirming whether those legacy-table references are dead code paths (safe to defer) or still reachable in production flow (not safe).

Parabéns pelo ótimo artigo Heloisa !
Aprendo demais com seus artigos e traduções.

Pesquisei um pouco mais sobre esse cenário porque ainda estou consolidando esse lado de IRIS Interoperability no estágio.

Pelo que entendi, esse 404 mesmo com a classe existindo geralmente cai em um destes pontos:

1. Nome da classe de dispatch errado: a aplicação web aponta para uma classe que não é exatamente a configurada (typo, caminho de pacote errado). A classe que "existe" pode não ser a mesma apontada no Dispatch.

2. Namespace: a classe existe onde você compilou, mas a aplicação web roda em outro namespace. Se o handler troca de namespace internamente, classes do namespace original podem ficar invisíveis e gerar <CLASS DOES NOT EXIST> por trás do 404.

3. URL map não bate com a URL chamada: a aplicação web só atende as rotas definidas no UrlMap da classe de dispatch. Rota não mapeada (ou faltando uma barra no final) também vira 404, mesmo com a classe inteira correta.

4. Classe não recompilada depois de importada ou alterada.

O que eu testaria primeiro: nome exato da classe no Dispatch, namespace de execução vs namespace de compilação, e o log CSP/ISCLOG pra ver se por trás do 404 tem um <CLASS DOES NOT EXIST> mais específico.

Essa é uma leitura baseada em pesquisa, ainda não passei exatamente por esse cenário, mas o padrão namespace + dispatch já vi gerar comportamento estranho em REST.

Pesquisei mais a fundo porque achei que a resposta automática deixou uma lacuna sobre o %Open().

Pelo que encontrei na documentação, os três métodos têm papéis diferentes:

%New() cria o objeto em memória, ainda não existe no banco.

%OpenId(id, concorrência, .status) abre um objeto existente a partir do Id, assumindo que você já sabe a qual classe ele pertence. É o caso mais comum: você tem o Id (por exemplo vindo de uma URL REST) e quer carregar o registro.

%Open(oid, concorrência, .status) abre um objeto a partir do OID, que é diferente do Id simples. O OID carrega o Id mais o nome da classe, e é usado com menos frequência. Achei um relato de alguém usando %Open() justamente quando a mesma estrutura de Id pode pertencer a classes diferentes, e o OID resolve isso sem você precisar saber de antemão qual classe abrir.

%Save() persiste (insert ou update) o objeto que está em memória, e sempre retorna um %Status que vale a pena testar antes de seguir.

Sobre a sua classe REST: pelo que você descreveu (herdando de %CSP.REST, UrlMap com GET), o fluxo comum dentro do método mapeado na rota seria usar %OpenId() com o Id que vier como parâmetro da URL, e só usar %Open() se você já estiver lidando com OID em mãos ou com referências que podem apontar para classes diferentes.

Essa parte do %Open() x %OpenId() eu tirei da documentação oficial, ainda não testei na prática esse cenário de classes diferentes, então se alguém já passou por isso e quiser confirmar, ajuda bastante.

Uma solução bem estruturada que demonstra de forma prática como integrar FHIR, IRIS for Health e IA para gerar resumos clínicos personalizados e escaláveis.

Hey Gabriela! had to ask Claude because I had no idea myself

Yeah, this is expected unfortunately. InvokeMethod uses $CLASSMETHOD under the hood, which doesn't validate parameter count or types, so when the signature changed to a single request object, the method still got invoked, returned $$$OK, but the output was never properly set. No SoapFault because the mismatch never even reaches the wire, it's purely local.

Safest fix is to call the WebClient method directly:

Set tSC = ##class(Your.WebClient).%New().YourMethod(tRequestObj)

Compile-time checking, if the signature changes, it won't compile instead of failing silently at runtime.

And always guard the output regardless:

If '$IsObject(tResponse) {
    Set tSC = $$$ERROR($$$GeneralError, "WebClient returned no response object")
    Quit tSC
}
Excelente conteúdo! Explica de forma clara como o DTR ajuda a padronizar e agilizar o cumprimento dos requisitos de documentação na autorização prévia.

Bom dia Vitor, 

Fui dar uma pesquisada sobre e resposta da Heloisa já dá um caminho bom. O problema é que IRIS_PYTHON_PATH no docker-compose só é lido na inicialização do container pelo entrypoint padrão para montar o PYTHONPATH do processo irisdb, mas isso não necessariamente manda pro sys.path que o Embedded Python usa dentro de uma sessão/classe.


Duas alternativas que vi sendo recomendadas:

1-Setar via iris.script no build, usando %SYS.Python para adicionar o path do venv de forma persistente, mas executando isso no iris.script durante o build, ou em um método de inicialização (%ZSTART ou classe de setup) que rode toda vez que o IRIS sobe, já que sys.path não persiste entre restarts

2-Instalar direto na pasta que o Embedded Python já reconhece (mgr/python), como a Heloisa sugeriu.

Resumo claro e didático de como a IA pode automatizar a correção de bugs, destacando seu potencial de tornar o desenvolvimento mais eficiente e adaptável.

Parabéns pelo ótimo artigo, vou ler as partes anteriores para me inteirar mais sobre o assunto.

Really useful to see Embedded Python and ObjectScript working together to handle FHIR data in a practical way

Excelente artigo, Heloisa! Estou começando agora no IRIS vindo de C#/.NET e o exemplo da tabela PERSON deixou bem claro pra mim por que registros com volumes tão diferentes competindo pelas mesmas Globals pesam na busca.