@Juliano Assis Segue um código bem básico e genérico para exportar dados para um arquivo CSV:

ClassMethod exportar(arquivo As %String) As %String
{
Open arquivo:"WN" // Abre o arquivo para escrita (W) e caso ele não exista cria o arquivo (N)
Set next=""
Do
{
Set next=$Order(^Global(next))
If next'=""
{ Set reg=$Get(^Global(next))
If $Piece(reg,"^",3)'=1
{
Set reg=next_","_$Piece(reg,"|",1)_","_$Piece(reg,"^",2)
Use arquivo Write reg,!
Set $Piece(^Global(next),"^",3)=1
}
}
While next'=""
Close arquivo
Quit "OK"
}

O código pega os registros da global que ainda não foram marcados como lido e exporta. Então marca o arquivo como lido. Uma próxima leitura pula este registro.

Pode substituir o uso do $Order por um SELECT recuperando os registros de uma tabela também.

Abraços,

Olá @Juliano Assis 

Dê uma olhada no post a seguir:

https://pt.community.intersystems.com/post/usando-o-python-no-intersyste...

O artigo mostra como gerar arquivos excel a partir de classes do InterSystems Iris usando Python. É bem simples e intuitivo.

Depois de gerada a rotina é coloca-la no Task Manager conforme a documentação  disponível: https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls...

Basicamente é usar a opção RunLegacyTask, informar a rotina e definir a periodicidade de execução.

Abraços 

Olá Gabriel,

Entendi que ao acionar a trigger o processo atualiza o banco externo. Talvez a carga de realizar as atualizações de maneira imediata esteja causando os problemas que você mencionou.

Uma possível abordagem é manter as triggers, mas não mais atualizar o banco externo, e sim gerar um log das atualizações a serem realizadas dentro do próprio Caché. E ter um processo apartado que faça as atualizações no banco externo a partir deste log.

Seria como se fosse uma fila, ou seja, as triggers colocam as informações no log de atualização, e o processo consome este log atualizando o banco externo.

Existe neste modelo a vantagem de a qualquer momento você poder reprocessar as atualizações, visto que os dados estarão no log. A desvantagem é um breve delay entre a execução no Caché e a replicação no PostGre, mas acredito por experiências passadas que este delay não será alto, pelo contrário, será bem baixo.

A inclusão dos dados no log não devem te gerar nenhum tipo de gargalo pois será uma estrutura do próprio Caché. E a atualização do banco externo será registro a registro, o que não deve gerar nenhum tipo de problema para sua infra pois terá um peso bem baixo de processamento.

Espero ter ajudado, e estou à sua disposição para conversarmos.

Um abraço!!

Olá Jenifer,

Montei o código a seguir para verificar a existência de globais em uma rotina.

A principio ele avalia uma rotina .MAC que fica com seu código na global ^rMAC mas você pode adapta-lo para verificar qualquer uma, inclusive métodos de classes ou qualquer outra estrutura com algum ajuste.

Pseudo ;Pseudo Interpretador
Set debug=1
Write !,"Rotina: " Read nome
If nome="" Quit
Kill ^dicionario(nome)
If '$Data(^rMAC(nome)) Write !,"Rotina não existe" Quit
Set nlin=+$Get(^rMAC(nome,0,0)) If nlin<1 Write !,"Não existem linhas na rotina" Quit
Set clin=0
Do 
{
Set clin=clin+1
If clin'>nlin
{
Set txt=^rMAC(nome,0,clin)
Set tam=$Length(txt)
Set pos=0
Set esc=0
Do
{
Set pos=pos+1
If pos'>tam
{
Set car=$Extract(txt,pos)
If car=""""
{
Set esc=$Select(esc=1:0,1:1)
If debug
{
If esc=0 Write !,">>>Fecha aspa"
Else  Write !,"<<<Abre aspa"
} Else {
If 'esc
{
If car="^"
{
If debug Write " <- Achou circunflexo: Vem uma global: "
Set gpos=pos
For  Set gpos=gpos+1,cpos=$Extract(txt,gpos) If cpos'?1A&(cpos'?1N) Quit
Set global=$Extract(txt,pos,gpos-1)
If debug Write global
Set ^dicionario(nome,global)=$Piece($Get(^dicionario(nome,global)),"|",1)+1_"|"_$Piece($Get(^dicionario(nome,global)),"|",2,9999)_"|"_clin_","_pos

Else {
If debug
{
Write !," >>>Texto dentro de aspa: ",car
}
}
}
}
While (pos<tam) }
While (clin<nlin)
Quit

Fiz um teste básico aqui e funcionou em teste para algumas rotinas minhas. 

A global criada ^dicionario, vai trazer a global na chave e como conteúdo o número de vezes que aparece no código seguido das posições onde aparece (linha e posição).

A variavel debug ativa/desativa um debug para ver o que está ocorrendo no código.

O código somente vai avaliar a rotina corrente. Se ele fizer chamadas a métodos ou outros códigos que manipulem globais ele não pegará.

Espero que ajude.