Manipulando Globais do InterSystems IRIS ao Estilo Python com iris-global-reference
Os globals do InterSystems IRIS são um dos principais pontos fortes da plataforma: eles armazenam dados hierárquicos em uma estrutura direta, ordenada e eficiente. Mas ao trabalhar com Python, manipular globals às vezes pode parecer mais próximo de uma API de baixo nível do que dos hábitos naturais da linguagem.

O projeto iris-global-reference fornece uma camada Python sobre os globals do IRIS. Seu objetivo é simples: tornar o acesso aos globals mais legível, mais idiomático e mais fácil de integrar em código Python moderno, sem esconder o modelo hierárquico subjacente.
Tags sugeridas: InterSystems IRIS, Python, Embedded Python, Globals, JSON
Por que este projeto?
Em ObjectScript, globals são naturais:
set ^demo("players",1)="Babe Ruth"
set ^demo("players",2)="Cy Young"
Em Python, frequentemente queremos escrever algo mais próximo de um dicionário:
team["players", "1"] = "Babe Ruth"
print(team["players"]["1"])
É exatamente isso que o iris-global-reference fornece com a classe GlobalReference.
O projeto atende a diversos casos de uso:
- manipular globals do IRIS com uma sintaxe mais Pythonica;
- percorrer facilmente uma árvore de globals;
- converter globals em dicionários Python ou JSON;
- importar dicionários ou JSON para o IRIS;
- usar a mesma API em Embedded Python ou a partir de uma conexão remota;
- encapsular operações comuns como
set,get,kill,$ORDER,$QUERYe transações.
Instalação
O pacote está disponível via pip:
pip install iris-global-reference
Para usá-lo diretamente em um terminal Python do IRIS, você também pode instalá-lo no diretório Python da instância:
pip install iris-global-reference --target=<mgr_dir>/python
Primeiro exemplo
Aqui está um exemplo mínimo usando um global ^demo:
from iris_global import GlobalReference
team = GlobalReference("^demo")
team.kill()
team.set((), "Baseball")
team["name"] = "Boston Red Sox"
team.set(("players", "1"), "Babe Ruth")
team.set(["players", "2"], "Cy Young")
team["players", "3"] = "Ted Williams"
print(team.get(()))
print(team["name"])
print(team["players"]["1"])
A mesma referência aceita múltiplos formatos de subscritos: string, lista ou tupla. Isso permite usar a API no estilo que melhor se adapta ao código chamador.
Uma API próxima de dicionários Python
GlobalReference expõe métodos explícitos:
team.set(("players", "1"), "Babe Ruth")
print(team.get(("players", "1")))
team.kill(("players", "1"))
Mas também suporta operações familiares do Python:
team["players", "1"] = "Babe Ruth"
if ("players", "1") in team:
print(team["players"]["1"])
del team["players", "1"]
Essa sintaxe é útil para escrever código de aplicação mais natural enquanto permanece alinhada ao modelo de dados dos globals.
Percorrendo um global
O projeto fornece diversos métodos de iteração:
for key in team.keys():
print(key)
for value in team.values():
print(value)
for key, value in team.items():
print(key, value)
Você também pode controlar o percurso:
for subscript in team.subscripts(("players",), children_only=True):
print(subscript, team.get(subscript))
Para desenvolvedores familiarizados com ObjectScript, order() e query() fornecem um comportamento próximo de $ORDER e $QUERY:
print(team.order(("players", "")))
print(team.query(("players",)))
Exportando um global para um dicionário ou JSON
Um dos benefícios do projeto é facilitar a conversão entre globals do IRIS e estruturas Python.
data = team.to_dict()
print(data)
Resultado de exemplo:
{
None: "Baseball",
"name": "Boston Red Sox",
"players": {
"1": "Babe Ruth",
"2": "Cy Young",
"3": "Ted Williams"
}
}
A chave None representa o valor do nó atual. Isso é necessário porque um nó de global do IRIS pode possuir tanto um valor quanto descendentes, enquanto um dicionário Python geralmente representa ou um valor ou um dicionário aninhado.
O mesmo conteúdo pode ser exportado para JSON:
json_data = team.to_json()
print(json_data)
No JSON, o valor do nó atual é representado por padrão pela chave _:
{
"_": "Baseball",
"name": "Boston Red Sox",
"players": {
"1": "Babe Ruth",
"2": "Cy Young",
"3": "Ted Williams"
}
}
A importação funciona no sentido inverso:
team.from_dict({
None: "Baseball",
"name": "Boston Red Sox",
"players": {
"1": "Babe Ruth",
"2": "Cy Young"
}
})
E para JSON:
team.from_json("""
{
"_": "Baseball",
"name": "Boston Red Sox",
"players": {
"1": "Babe Ruth",
"2": "Cy Young"
}
}
""")
Embedded Python ou conexão remota
A API pode ser usada a partir de Embedded Python sem fornecer uma conexão:
from iris_global import GlobalReference
team = GlobalReference("^demo")
team["name"] = "Boston Red Sox"
Ela também pode ser usada a partir de um programa Python externo com uma conexão nativa IRIS:
import iris
from iris_global import GlobalReference
conn = iris.connect("localhost", 1972, "USER", "SuperUser", "SYS")
team = GlobalReference("^demo", connection=conn)
team["name"] = "Boston Red Sox"
print(team["name"])
O projeto utiliza a conexão nativa fornecida por iris.connect(...).
Transações
As transações são expostas por meio de um context manager Python:
from iris_global import GlobalReference
team = GlobalReference("^demo")
with team.transaction():
team["name"] = "Boston Red Sox"
team["players", "1"] = "Babe Ruth"
Se o bloco for concluído com sucesso, a transação é confirmada. Se uma exceção for lançada, ela será revertida.
A classe também pode ser usada diretamente com with:
with GlobalReference("^demo") as team:
team["name"] = "Boston Red Sox"
Suporte experimental a arrays
Globals do IRIS não possuem um conceito nativo de array no sentido de JSON ou Python. Para suportar importação e exportação de listas, o projeto utiliza uma convenção de serialização.
Por exemplo:
gref = GlobalReference("^demo")
gref.from_dict({
"name": "example",
"numbers": [1, 2, 3]
})
print(gref.to_dict())
O array é armazenado no global com um prefixo interno, __array__ por padrão, e então reconstruído como uma lista Python durante a exportação. Essa parte ainda é experimental, mas já torna trocas com estruturas similares a JSON mais convenientes.
Exibindo conteúdo como ZWRITE
Para depuração ou para verificar rapidamente a estrutura armazenada, o método zw() retorna uma saída próxima de ZWRITE:
print(team.zw())
Exemplo:
^demo="Baseball"
^demo("name")="Boston Red Sox"
^demo("players","1")="Babe Ruth"
^demo("players","2")="Cy Young"
Isso é útil quando você deseja comparar o resultado em Python com o que escreveria ou inspecionaria a partir do ObjectScript.
Comparação rápida com APIs nativas
O objetivo do projeto não é substituir as APIs nativas do IRIS, mas adicionar uma camada de conveniência para casos em que você está principalmente escrevendo Python.
Por exemplo, com iris-global-reference:
global_reference.set(("name", 1), "Boston Red Sox")
value = global_reference.get(("name", 1))
Com uma API nativa, a ordem dos argumentos e o tratamento de subscritos podem ser diferentes. Esta biblioteca padroniza o uso em torno de uma convenção Python: primeiro o caminho do nó, depois o valor.
Quando você deve usar este projeto?
iris-global-reference é especialmente útil se você:
- desenvolve com Embedded Python e InterSystems IRIS;
- escreve scripts Python que precisam ler ou popular globals;
- deseja expor dados de globals como JSON;
- deseja manipular estruturas hierárquicas do IRIS com dicionários Python;
- deseja prototipar rapidamente sem escrever muito ObjectScript;
- precisa de uma API mais legível para operações comuns em globals.
Roadmap
O roadmap atual inclui:
- suporte mais avançado a arrays;
- suporte mais completo a dados binários;
- tipos IRIS como listbuild, vector, PVA ou bit;
- suporte a variáveis multidimensionais.
Testando o projeto
O repositório contém uma suíte de testes. Para executá-la:
python -m pytest
Conclusão
iris-global-reference é uma biblioteca pequena, mas resolve um problema concreto: tornar globals do IRIS mais agradáveis de manipular a partir do Python.
Ela preserva as operações fundamentais do modelo IRIS enquanto adiciona uma experiência próxima de dicionários Python, conversões práticas para JSON, iteradores e uso tanto em Embedded Python quanto em conexões remotas.
Para desenvolvedores que trabalham na interseção entre InterSystems IRIS e Python, é uma ferramenta simples de experimentar e fácil de integrar em scripts, protótipos ou aplicações mais estruturadas.
Links: