#Bancos de dados

0 Seguidores · 40 Postagens

O banco de dados InterSystems Caché é um arquivo onde todos os dados, scripts de aplicações e usuários, funções e configurações de segurança são armazenados. Normalmente, o nome do arquivo é cache.dat.

Documentação.

Artigo Heloisa Paiva · Set. 9, 2025 3m read

Rubrica InterSystems FAQ

Você pode verificar o espaço em disco a qualquer momento usando a classe utilitária do sistema: SYS.Database e a consulta: FreeSpace.

Aqui está como testar no terminal IRIS (vá para o namespace %SYS e então execute):

zn"%SYS"set stmt=##class(%SQL.Statement).%New()
set st=stmt.%PrepareClassQuery("SYS.Database","FreeSpace")
set rset=stmt.%Execute()
do rset.%Display()

O exemplo de resultado de saída é o seguinte:

0
0 20
Artigo Larissa Prussak · Jun. 17, 2025 3m read

Se você está migrando do Oracle para o InterSystems IRIS — como muitos dos meus clientes — pode se deparar com padrões específicos de SQL do Oracle que precisam ser adaptados.

Veja esse examplo:

SELECT (TO_DATE('2023-05-12','YYYY-MM-DD') - LEVEL + 1) AS gap_date
FROM dual
CONNECT BY LEVEL <= (TO_DATE('2023-05-12','YYYY-MM-DD') - TO_DATE('2023-05-02','YYYY-MM-DD') + 1);

No Oracle:

0
0 25
Pergunta Graciano dos Santos Duarte · Jun. 2, 2025

Prezado senhores,

Estou tentando consultar os dados das tabelas de um banco de dados caché. Ele possui dados nas globais.  Também possui tabelas SQL sem registros, mas com a estrutura das classes do banco de dados. Quando vou consultar os dados através do driver ODBC não retorna nenhum dado. Mesmo pelo painel administrativo as consultas SQL não retornam dados. Sabem me dizer o que pode estar acontecendo?

At.te

Graciano dos Santos Duarte

5
0 61
Artigo Heloisa Paiva · Maio 26, 2025 8m read

Introdução

Olá! Neste artigo, discutirei a degradação de banco de dados, um tipo de problema de integridade de dados que se pode enfrentar ao usar o IRIS. Primeiro, farei uma revisão da estrutura dos bancos de dados IRIS. Em seguida, discutirei como a degradação de banco de dados pode se manifestar e as causas comuns de problemas de degradação. Concluirei com dicas gerais que damos aos nossos clientes sobre como prevenir ou se preparar para problemas de degradação de banco de dados.

Estrutura do Banco de Dados IRIS

O que exatamente é um banco de dados? Um banco de dados IRIS é um único arquivo que consiste em uma unidade fundamental chamada "bloco". Ele contém vários blocos de tamanhos iguais (normalmente 8kb) em ordem sequencial. Todos esses blocos "apontam" uns para os outros armazenando o offset no banco de dados onde reside o bloco para o qual apontam. Essa rede de blocos forma uma configuração que se assemelha a uma "floresta" do que são chamadas de árvores balanceadas, ou B-trees. Cada global é representada por uma B-tree separada, e cada B-tree é acessível por meio de um Bloco de Diretório Global de nível superior que contém ponteiros para todas as B-trees globais no banco de dados.

A característica que define uma B-tree é que todos os blocos de dados de "folha" estão no mesmo nível. Isso significa que, sempre que um bloco de ponteiro superior é preenchido, outra camada de ponteiro é adicionada acima dele, permitindo que a B-tree escale teoricamente de forma indefinida. No início de cada bloco, há uma quantidade de bytes que indicam alguns metadados sobre aquele bloco e os blocos ao seu redor. Por exemplo, cada bloco contém informações sobre seu número de bloco, a quantidade de bytes de dados no bloco, o tipo de bloco (ponteiro ou dados), a ordenação, etc. O bloco também contém informações sobre blocos relacionados, como o número do bloco à sua direita, o primeiro nó do bloco à sua direita e as diferenças de byte entre o último nó do bloco e o bloco à direita.

Aqui está uma representação de como se parece uma B-tree global. As linhas verdes representam ponteiros entre diferentes níveis de blocos, e as linhas laranja representam ponteiros entre os blocos e seus blocos vizinhos à direita. Um valor de bloco à direita de 0 é usado quando o bloco está na borda direita da árvore.

image

Degradação do Banco de Dados

Problemas de integridade do banco de dados ocorrem quando a estrutura interna de um banco de dados apresenta alguma inconsistência lógica, ou quando o banco de dados não corresponde ao formato que o IRIS espera. Isso pode acontecer de várias maneiras:

  • Integridade Referencial: Os ponteiros entre blocos de ponteiros e blocos de dados, ou os ponteiros de direção "direita" entre blocos de dados, estão inconsistentes. Por exemplo, um bloco de ponteiros pode indicar que o primeiro nó de um bloco de dados para o qual ele aponta é ^x(10), enquanto o primeiro nó desse bloco de dados é, na verdade, ^x(20).
  • **Integridade dos Dados: ** Os dados dos blocos de ponteiros ou dos blocos de dados estão corrompidos. Por exemplo, os primeiros bytes de cada bloco contêm metadados sobre o próprio bloco e seus blocos relacionados, começando no offset 0. Se estes estiverem localizados em outro offset, isso resultaria na corrupção do bloco.
  • Integridade da Aplicação: Isso ocorre quando o banco de dados está no formato esperado pelo IRIS, mas há alguma inconsistência lógica relacionada a como a aplicação deveria funcionar. Por exemplo, digamos que esperamos que todos os dados do médico sejam salvos no global ^Hospital.DoctorsD, e os índices desses médicos sejam salvos no ^Hospital.DoctorsI. Se um médico tivesse seus dados no global de dados, mas não tivesse um índice correspondente no global de índices, isso seria uma forma de problema de integridade da aplicação.

Causas Comuns de Degradação

Aqui, abordarei algumas das causas comuns de degradação do banco de dados que observamos em nossos clientes.

Cache de Escrita do Windows

O cache de escrita do Windows é um recurso do Windows que pode levar a problemas de degradação do banco de dados. A ideia por trás dessa configuração é que o Windows armazenará em buffer as escritas em disco na memória e as gravará no disco em pacotes maiores. Isso ajuda a melhorar o desempenho em certos casos, pois as escritas em disco são lentas, e fazê-las em pacotes maiores permite uma escrita mais eficiente. Por exemplo, imagine que seu disco esteja dividido em blocos de 1024 bytes, e você tenha um aplicativo tentando escrever 256 blocos de dados de 4 bytes. Em vez de fazer 256 escritas separadas no disco, o que seria bastante lento, o cache de escrita economiza tempo armazenando essas escritas na memória e gravando-as com muito menos frequência.

No entanto, isso pode criar problemas quando há perda de energia. Se o sistema operacional estiver armazenando dados na memória que normalmente já teriam sido gravados no disco, uma perda de energia pode fazer com que esses dados sejam perdidos e irrecuperáveis, já que a memória RAM é volátil. Por essa razão, frequentemente recomendamos que nossos clientes desativem o cache de escrita do Windows quando não for necessário.

Cache de Escrita de Hardware

Assim como os sistemas operacionais usarão a RAM para armazenar em cache as gravações em disco, algumas unidades de disco de nível empresarial também armazenarão em cache as gravações em disco para fins de eficiência. Certos SSDs, por exemplo, contêm um buffer DRAM que pode armazenar gravações para escrevê-las em grandes pacotes para aumentar o desempenho. Infelizmente, assim como no cache de escrita em nível de sistema operacional, a DRAM e a memória de hardware em geral são voláteis e não serão preservadas em caso de perda de energia. Isso pode ser mitigado garantindo que a unidade de disco seja alimentada por baterias ou alguma outra forma de Sistema de Alimentação Ininterrupta (UPS) para que possa descarregar o buffer de memória em caso de falha de energia.

VMware

VMware é uma solução de hospedagem em nuvem que muitos de nossos clientes usam para executar nossos produtos. Houve uma série de problemas conhecidos com o VMware que podem levar a problemas de integridade de dados. Estes são detalhados nos seguintes avisos:

  • Aviso: VMWare vSAN e Integridade de Dados (link) : Há um problema conhecido relacionado a operações de extensão de disco com VMs executando VMware vSAN, uma solução de armazenamento oferecida pela VMware.
  • Aviso: VMWare vSphere e Integridade de Dados (link) : O SEsparse, um formato de snapshot para máquinas VMware, possui um problema conhecido de integridade de dados.
  • Aviso: Erros de Consistência de Dados do VMware vSAN (link) : Existem certas instruções x86 no conjunto de instruções AVX-512 que podem levar a problemas de integridade de dados quando usadas com o vSAN.

Aconselhamento Geral

Aqui estão algumas recomendações gerais que fornecemos aos nossos clientes ao ajudá-los a se recuperar de problemas de degradação do banco de dados.

Backups

Ao lidar com problemas de degradação do banco de dados, nosso primeiro recurso, surpreendentemente, não é tentar reparar. Reparar bancos de dados manualmente pode ser um processo complicado e nem sempre produtivo, devido à grande escala e complexidade dos problemas típicos de degradação. Em vez disso, inicialmente tentaremos recuperar de um backup para restaurar o banco de dados a um estado saudável. Por essa razão, pedimos aos nossos clientes que façam backups frequentes.

Os backups também são extremamente úteis para realizar uma Análise da Causa Raiz (ACR) sobre o porquê da degradação ter ocorrido em primeiro lugar. Com um backup, podemos ver como era o estado saudável para comparação com o estado não saudável. Também podemos ver como a degradação mudou ou se espalhou ao longo do tempo para rastrear sua origem.

Guia para fazer backups: link

Verificações de Integridade

É vital para a ACR que detectemos a degradação do banco de dados o mais rápido possível. Isso é importante porque, muitas vezes, a degradação acontece devido a algum aspecto do estado do sistema, seja no nível da aplicação, do sistema operacional ou do hardware.

Por essa razão, pedimos aos nossos clientes que executem verificações frequentes da rotina ^Integrity. Essa rotina verifica bancos de dados e globais para garantir que eles tenham o formato esperado pelo IRIS. Se você encontrar degradação em seus bancos de dados, pode entrar em contato imediatamente com o WRC (Worldwide Response Center) e nós o auxiliaremos no reparo e, em seguida, na realização de uma Análise da Causa Raiz (ACR) para encontrar a origem do problema.

Guia para executar verificações de integridade: link

Também é importante executar verificações de integridade fora do IRIS no sistema operacional e no hardware em que a instância do IRIS está sendo executada, pois o IRIS funciona de forma intrínseca com o sistema operacional e o hardware para gerenciar os dados corretamente. Isso pode ser feito por meio de utilitários do sistema operacional, como fsck (UNIX) e chkdsk (Windows).

Conclusão

No mundo dos dispositivos de armazenamento modernos e sistemas operacionais avançados, os problemas de integridade de dados não são tão frequentes quanto antes. No entanto, eles ainda ocorrem e podem levar a problemas sérios com a disponibilidade da aplicação e perda de dados quando acontecem. Para isso, pedimos aos nossos clientes que verifiquem frequentemente a integridade de seus dados e sistemas, e nos contatem sempre que identificarem um problema, para que possamos ajudar a restaurar seus sistemas o mais rápido possível. Obrigado!

0
0 30
Artigo Heloisa Paiva · Maio 8, 2025 4m read

Migrar de Oracle, MSSQL ou outros sistemas de banco de dados puramente relacionais para um InterSystems IRIS multimodel é uma decisão estratégica que requer planejamento e execução cuidadosos. Embora essa transição ofereça benefícios significativos, incluindo desempenho aprimorado, escalabilidade e suporte para arquiteturas modernas, ela também apresenta desafios. Neste artigo, destacarei algumas das considerações relacionadas à codificação para garantir uma migração bem-sucedida. Deixarei tudo o que está conectado a uma migração real de estruturas e dados fora do escopo deste artigo.

Primeiramente, ao considerar migrar para um sistema de banco de dados diferente, você precisa entender sua lógica de negócios, seja ela do lado da aplicação (servidor de aplicação) ou do servidor de banco de dados. Basicamente, onde você tem suas instruções SQL que potencialmente precisará reescrever?

0
0 32
InterSystems Oficial Danusa Calixto · Abr. 3, 2025

Resumo de Alertas

Alerta ID Produto & Versões Afectadas Requisitos Explícitos
DP-439207  InterSystems IRIS® data platform 2024.3 (AIX) Instalações AIX Usando JSON e conjuntos de Caracteres Unicode non-Latin-1 
DP-439280  InterSystems IRIS 2024.3 (containers com IntegratedML)  IntegratedML Containers usando TensorFlow

Detalhes dos Alertas

DP-439207 - Problemas no Parser JSON Unicode em AIX

0
0 28
Artigo Heloisa Paiva · jan 28, 2025 4m read

Não tenho certeza se muitos se conectam ao MS SQL para executar consultas, procedimentos armazenados, etc., mas nosso Sistema de Saúde possui muitos bancos de dados baseados em MS SQL que utilizamos no ambiente de Interoperabilidade por vários motivos.

Com a migração do ambiente local para a nuvem, enfrentamos algumas dificuldades com as conexões do SQL Gateway e como configurá-las para usar o Microsoft Entra para autenticação do Active Directory.

0
0 37
Artigo Heloisa Paiva · Nov. 8, 2024 1m read

Perguntas frequentes da InterSystems 

O número máximo de namespaces que se podem criar em uma instância é de 2047. No entanto, para utilizar um grande número de namespaces, é necessário configurar a memória adequadamente.

O número máximo de bases de dados (incluso as bases de dados remotas) que se pode criar em uma instância é de 15.998. Dependendo do tipo de licença, pode haver restrições sobre a quantidade que se pode criar. Para mais detalhes, consulte o seguinte documento.

Configuração da Base de Dados [IRIS]
Configuração da Base de Dados

0
0 28
Artigo Edilson Eberle Carvalho · Set. 17, 2024 6m read

Como estou desenvolvendo uma aplicação para auditoria de arquivo fiscal digital, EFD ICMS IPI, optei por armazenar os dados diretamente em globais. Uma vez que os registros do arquivo EFD são formato txt e tem características semelhantes às linhas de registro de global.

Para poder analisar os itens de saída das Notas Fiscais Eletrônicas, fiz a importação também dos dados destes arquivos, e os armazenei em global. Segue exemplo:

0
0 41
Artigo Heloisa Paiva · Ago. 31, 2024 5m read

Rubrica InterSystems FAQ 

Os dados dos produtos InterSystems (linha de tabela, instância de objeto) são guardados em variáveis globais.
O tamanho de dados de cada global pode ser obtido clicando nas propriedades da global que você quer ver da página Portal de Adminitração > Sistema > Configuração > Base de dados Local > Globais, então clicando no botão Calcular Tamanho na página de atributos globais que aparece.
Para exibir os tamanhos de globais num namespace, você pode usar ^%GSIZE no terminal
A execução do método é a seguinte:

0
0 56
Artigo Heloisa Paiva · Ago. 21, 2024 29m read

Um experimento sobre como usar a framework LangChain, Busca por Vetor IRIS e LLMs para gerar SQL compatível com IRIS de prompts de usuários.

Esse artigo foi baseado neste notebook. Você pode rodar com um ambiente pronto para uso com esta aplicação no OpenExchange.

Setup

Primeiro, precisamos instalar as livrarias necessárias:

!pip install --upgrade --quiet langchain langchain-openai langchain-iris pandas

Em seguida, importamos os módulos requeridos e definimos o ambiente:

import os
import datetime
import hashlib
from copy import deepcopy
from sqlalchemy import create_engine
import getpass
import pandas as pd
from langchain_core.prompts import PromptTemplate, ChatPromptTemplate
from langchain_core.example_selectors import SemanticSimilarityExampleSelector
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain.docstore.document import Document
from langchain_community.document_loaders import DataFrameLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain_core.output_parsers import StrOutputParser
from langchain.globals import set_llm_cache
from langchain.cache import SQLiteCache
from langchain_iris import IRISVector

Vamos usar SQLiteCache para manter as chamadas de LLM em cache:

# Cache for LLM calls
set_llm_cache(SQLiteCache(database_path=".langchain.db"))

Defina os parâmetros da conexão da base de dados IRIS:

# IRIS database connection parameters
os.environ["ISC_LOCAL_SQL_HOSTNAME"] = "localhost"
os.environ["ISC_LOCAL_SQL_PORT"] = "1972"
os.environ["ISC_LOCAL_SQL_NAMESPACE"] = "IRISAPP"
os.environ["ISC_LOCAL_SQL_USER"] = "_system"
os.environ["ISC_LOCAL_SQL_PWD"] = "SYS"

Se a chave da OpenAI API não está definida, peça ao usuário para fornecê-la:

if not "OPENAI_API_KEY" in os.environ:
    os.environ["OPENAI_API_KEY"] = getpass.getpass()

Crie a string de conxão para a base de dados IRIS:

# IRIS database connection string
args = {
    'hostname': os.getenv("ISC_LOCAL_SQL_HOSTNAME"), 
    'port': os.getenv("ISC_LOCAL_SQL_PORT"), 
    'namespace': os.getenv("ISC_LOCAL_SQL_NAMESPACE"), 
    'username': os.getenv("ISC_LOCAL_SQL_USER"), 
    'password': os.getenv("ISC_LOCAL_SQL_PWD")
}
iris_conn_str = f"iris://{args['username']}:{args['password']}@{args['hostname']}:{args['port']}/{args['namespace']}"

Estabeleça a conexão para a base de dados IRIS:

# Connection to IRIS database
engine = create_engine(iris_conn_str)
cnx = engine.connect().connection

Prepare um dicionário para guardar informações de contexto para o prompt do sistema:

# Dict for context information for system prompt
context = {}
context["top_k"] = 3

Criação de Prompt

Para transformar inputs de usuário em consultas SQL compatíveis com a base de dados IRIS, precisamos criar um prompt efetivo para o modelo de linguagem. Começamos com um prompt inicial que fornece instruções básicas para gerar queries SQL. O template é derivado de prompts default do LangChain's para MSSQL e customizado para a base de dados IRIS.

# Basic prompt template with IRIS database SQL instructions
iris_sql_template = """
Você é um expert em InterSystems IRIS. Dada uma questão como entrada, crie primeiro uma consulta com sintaxe correta para rodar e retorne a resposta para a questão de entrada.
A não ser que o usuário especifique na questão um número específico de exemplos a obter, pesquise por no máximo {top_k} resultados usando a cláusula TOP para o InterSystems IRIS. Você pode ordenar resultados para os dados mais informativos na base de dados.
Nunca pesquise todas as colunas de uma tabela. Você deve consultar apenas as colunas necessárias para responder a questão. Envolva cada nome de coluna em aspas simples para deontar que são identificadores delimitados.
Preste atenção para usar apenas nomes de colunas que você pode ver nas tabelas abaixo. Cuidado para não consultar colunas que não existem. Além disso, preste atenção em qual coluna está em qual tabela.
Atente-se em usar a função CAST(CURRENT_DATE as date) para buscar a data atual, se a questão envolve "hoje".
Use aspas duplas para delimitar identificadores de colunas.
Retorne apenas SQL puro; não aplique nenhum tipo de formatação.
"""

Esse prompt básico configura o modelo de linguagem (LLM) para funcionar como um expert em SQL com guia específico para a base de dados IRIS. Em seguida, fornecemos um prompt auxiliar com informação sobre a base de dados para evitar exageros.

# SQL template extension for including tables context information
tables_prompt_template = """
Only use the following tables:
{table_info}
"""

Para melhorar a acurácia das respostas LLM, usamos uma técnica chamada few-shot prompting. Isso envolve apresentar alguns exemplos para a LLM.

# SQL template extension for including few shots
prompt_sql_few_shots_template = """
Below are a number of examples of questions and their corresponding SQL queries.

{examples_value}
"""

Definimos o template para exemplos few-shot:

# Few shots prompt template
example_prompt_template = "User input: {input}\nSQL query: {query}"
example_prompt = PromptTemplate.from_template(example_prompt_template)

Construímos o prompt de usuário usando o template few-shot:

# User prompt template
user_prompt = "\n" + example_prompt.invoke({"input": "{input}", "query": ""}).to_string()

Finalmente, podemos compor todos os prompts para criar o prompt final:

# Complete prompt template
prompt = (
    ChatPromptTemplate.from_messages([("system", iris_sql_template)])
    + ChatPromptTemplate.from_messages([("system", tables_prompt_template)])
    + ChatPromptTemplate.from_messages([("system", prompt_sql_few_shots_template)])
    + ChatPromptTemplate.from_messages([("human", user_prompt)])
)
prompt

Esse prompt espera as variáveis examples_value, input, table_info, etop_k.

É assim que o prompt é estruturado:

ChatPromptTemplate(
    input_variables=['examples_value', 'input', 'table_info', 'top_k'], 
    messages=[
        SystemMessagePromptTemplate(
            prompt=PromptTemplate(
                input_variables=['top_k'], 
                template=iris_sql_template
            )
        ), 
        SystemMessagePromptTemplate(
            prompt=PromptTemplate(
                input_variables=['table_info'], 
                template=tables_prompt_template
            )
        ), 
        SystemMessagePromptTemplate(
            prompt=PromptTemplate(
                input_variables=['examples_value'], 
                template=prompt_sql_few_shots_template
            )
        ), 
        HumanMessagePromptTemplate(
            prompt=PromptTemplate(
                input_variables=['input'], 
                template=user_prompt
            )
        )
    ]
)

Para visualizar como o prompt será enviado a LLM, podemos usar valores no espaço reservado para as variáveis requeridas:

prompt_value = prompt.invoke({
    "top_k": "<top_k>",
    "table_info": "<table_info>",
    "examples_value": "<examples_value>",
    "input": "<input>"
})
print(prompt_value.to_string())
Sistema: 
Você é um expert em InterSystems IRIS. Dada uma questão como entrada, crie primeiro uma consulta com sintaxe correta para rodar e retorne a resposta para a questão de entrada.
A não ser que o usuário especifique na questão um número específico de exemplos a obter, pesquise por no máximo {top_k} resultados usando a cláusula TOP para o InterSystems IRIS. Você pode ordenar resultados para os dados mais informativos na base de dados.
Nunca pesquise todas as colunas de uma tabela. Você deve consultar apenas as colunas necessárias para responder a questão. Envolva cada nome de coluna em aspas simples para deontar que são identificadores delimitados.
Preste atenção para usar apenas nomes de colunas que você pode ver nas tabelas abaixo. Cuidado para não consultar colunas que não existem. Além disso, preste atenção em qual coluna está em qual tabela.
Atente-se em usar a função CAST(CURRENT_DATE as date) para buscar a data atual, se a questão envolve "hoje".
Use aspas duplas para delimitar identificadores de colunas.
Retorne apenas SQL puro; não aplique nenhum tipo de formatação.

Sistema: 
Use  apenas as tabelas a seguir:
<table_info>

Sistema: 
Abaixo, seguem alguns exemplos de questões e suas consultas SQL correspondentes.

<examples_value>

Humano: 
Input do usuário: <input>
Consulta SQL: 

Agora estamos prontos para enviar esse prompt para o LLM providenciando as variáveis necessárias. Vamos seguir para o próximo passo quando estiver pronto.

Fornecendo informações de tabela

Para criar consultas SQL precisas, precisamos fornecer ao modelo de linguagem (LLM) informações detalhadas sobre as tabelas das bases de dados. Sem essa informação, o LLM deve gerar consultas que parecem plausíveis mas são incorretas devido a exageros. Então, nosso primeiro passo é criar uma função que retorna definições de tabelas da base de dados IRIS.

Função para retornar definições de tabelas

A função a seguir consulta a variável INFORMATION_SCHEMA para buscar as definições de tabela para um schema (esquema) específico. Se uma tabela específica for fornecida, ela retorna a definição daquela tabela; caso contrário, retorna definições para todas as tabelas naquele esquema.

def get_table_definitions_array(cnx, schema, table=None):
    cursor = cnx.cursor()

    # Base query to get columns information
    query = """
    SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT, PRIMARY_KEY, null EXTRA
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_SCHEMA = %s
    """
    
    # Parameters for the query
    params = [schema]

    # Adding optional filters
    if table:
        query += " AND TABLE_NAME = %s"
        params.append(table)
    
    # Execute the query
    cursor.execute(query, params)

    # Fetch the results
    rows = cursor.fetchall()
    
    # Process the results to generate the table definition(s)
    table_definitions = {}
    for row in rows:
        table_schema, table_name, column_name, column_type, is_nullable, column_default, column_key, extra = row
        if table_name not in table_definitions:
            table_definitions[table_name] = []
        table_definitions[table_name].append({
            "column_name": column_name,
            "column_type": column_type,
            "is_nullable": is_nullable,
            "column_default": column_default,
            "column_key": column_key,
            "extra": extra
        })

    primary_keys = {}
    
    # Build the output string
    result = []
    for table_name, columns in table_definitions.items():
        table_def = f"CREATE TABLE {schema}.{table_name} (\n"
        column_definitions = []
        for column in columns:
            column_def = f"  {column['column_name']} {column['column_type']}"
            if column['is_nullable'] == "NO":
                column_def += " NOT NULL"
            if column['column_default'] is not None:
                column_def += f" DEFAULT {column['column_default']}"
            if column['extra']:
                column_def += f" {column['extra']}"
            column_definitions.append(column_def)
        if table_name in primary_keys:
            pk_def = f"  PRIMARY KEY ({', '.join(primary_keys[table_name])})"
            column_definitions.append(pk_def)
        table_def += ",\n".join(column_definitions)
        table_def += "\n);"
        result.append(table_def)

    return result

Retornar definições de tabela para um Esquema

Para esse exemplo, usamos o esquema Aviation (aviação), que está disponível aqui.

# Retrieve table definitions for the Aviation schema
tables = get_table_definitions_array(cnx, "Aviation")
print(tables)

Essa função retorna os predicados CREATE TABLE para todas as tabelas no esquema Aviation:

[
    'CREATE TABLE Aviation.Aircraft (\n  Event bigint NOT NULL,\n  ID varchar NOT NULL,\n  AccidentExplosion varchar,\n  AccidentFire varchar,\n  AirFrameHours varchar,\n  AirFrameHoursSince varchar,\n  AirFrameHoursSinceLastInspection varchar,\n  AircraftCategory varchar,\n  AircraftCertMaxGrossWeight integer,\n  AircraftHomeBuilt varchar,\n  AircraftKey integer NOT NULL,\n  AircraftManufacturer varchar,\n  AircraftModel varchar,\n  AircraftRegistrationClass varchar,\n  AircraftSerialNo varchar,\n  AircraftSeries varchar,\n  Damage varchar,\n  DepartureAirportId varchar,\n  DepartureCity varchar,\n  DepartureCountry varchar,\n  DepartureSameAsEvent varchar,\n  DepartureState varchar,\n  DepartureTime integer,\n  DepartureTimeZone varchar,\n  DestinationAirportId varchar,\n  DestinationCity varchar,\n  DestinationCountry varchar,\n  DestinationSameAsLocal varchar,\n  DestinationState varchar,\n  EngineCount integer,\n  EvacuationOccurred varchar,\n  EventId varchar NOT NULL,\n  FlightMedical varchar,\n  FlightMedicalType varchar,\n  FlightPhase integer,\n  FlightPlan varchar,\n  FlightPlanActivated varchar,\n  FlightSiteSeeing varchar,\n  FlightType varchar,\n  GearType varchar,\n  LastInspectionDate timestamp,\n  LastInspectionType varchar,\n  Missing varchar,\n  OperationDomestic varchar,\n  OperationScheduled varchar,\n  OperationType varchar,\n  OperatorCertificate varchar,\n  OperatorCertificateNum varchar,\n  OperatorCode varchar,\n  OperatorCountry varchar,\n  OperatorIndividual varchar,\n  OperatorName varchar,\n  OperatorState varchar,\n  Owner varchar,\n  OwnerCertified varchar,\n  OwnerCountry varchar,\n  OwnerState varchar,\n  RegistrationNumber varchar,\n  ReportedToICAO varchar,\n  SeatsCabinCrew integer,\n  SeatsFlightCrew integer,\n  SeatsPassengers integer,\n  SeatsTotal integer,\n  SecondPilot varchar,\n  childsub bigint NOT NULL DEFAULT $i(^Aviation.EventC("Aircraft"))\n);',
    'CREATE TABLE Aviation.Crew (\n  Aircraft varchar NOT NULL,\n  ID varchar NOT NULL,\n  Age integer,\n  AircraftKey integer NOT NULL,\n  Category varchar,\n  CrewNumber integer NOT NULL,\n  EventId varchar NOT NULL,\n  Injury varchar,\n  MedicalCertification varchar,\n  MedicalCertificationDate timestamp,\n  MedicalCertificationValid varchar,\n  Seat varchar,\n  SeatbeltUsed varchar,\n  Sex varchar,\n  ShoulderHarnessUsed varchar,\n  ToxicologyTestPerformed varchar,\n  childsub bigint NOT NULL DEFAULT $i(^Aviation.AircraftC("Crew"))\n);',
    'CREATE TABLE Aviation.Event (\n  ID bigint NOT NULL DEFAULT $i(^Aviation.EventD),\n  AirportDirection integer,\n  AirportDistance varchar,\n  AirportElevation integer,\n  AirportLocation varchar,\n  AirportName varchar,\n  Altimeter varchar,\n  EventDate timestamp,\n  EventId varchar NOT NULL,\n  EventTime integer,\n  FAADistrictOffice varchar,\n  InjuriesGroundFatal integer,\n  InjuriesGroundMinor integer,\n  InjuriesGroundSerious integer,\n  InjuriesHighest varchar,\n  InjuriesTotal integer,\n  InjuriesTotalFatal integer,\n  InjuriesTotalMinor integer,\n  InjuriesTotalNone integer,\n  InjuriesTotalSerious integer,\n  InvestigatingAgency varchar,\n  LightConditions varchar,\n  LocationCity varchar,\n  LocationCoordsLatitude double,\n  LocationCoordsLongitude double,\n  LocationCountry varchar,\n  LocationSiteZipCode varchar,\n  LocationState varchar,\n  MidAir varchar,\n  NTSBId varchar,\n  NarrativeCause varchar,\n  NarrativeFull varchar,\n  NarrativeSummary varchar,\n  OnGroundCollision varchar,\n  SkyConditionCeiling varchar,\n  SkyConditionCeilingHeight integer,\n  SkyConditionNonCeiling varchar,\n  SkyConditionNonCeilingHeight integer,\n  TimeZone varchar,\n  Type varchar,\n  Visibility varchar,\n  WeatherAirTemperature integer,\n  WeatherPrecipitation varchar,\n  WindDirection integer,\n  WindDirectionIndicator varchar,\n  WindGust integer,\n  WindGustIndicator varchar,\n  WindVelocity integer,\n  WindVelocityIndicator varchar\n);'
]

Com essas definições de tabela, podemos seguir para o próximo passo, que é integrá-las ao nosso prompt para o LLM. Isso assegura que o LLM tem informações precisas e compreensivas sobre o esquema da base de dados ao gerar consultas SQL.

Selecionando as tabelas mais relevantes

Ao trabalhar com bases de dados, especialmente as maiores, enviar a linguagem de definição de dados (Data Definition Language ou DDL) para todas as tabelas em um prompt pode ser impraticável. Ao passo que essa abordagem pode funcionar para bases de dados menores, as bases de dados reais frequentemente contém centenas ou milhares de tabelas, sendo ineficiente processá-las por completo.

No entanto, é improvável que um modelo de linguagem precise saber cada tabela numa base de dados para gerar consultas SQL efetivamente. Para endereçar esse desafio, podemos nivelar as capacidades da procura semântica para selecionar apenas tabelas relevantes baseadas na consulta do usuário.

Abordagem

Nós podemos conseguir isso usando a procura semântica com a Procura de Vetor IRIS. Note que este método é mais efetivo se os seus identificadores de elementos SQL (como tabelas, campos e chaves) têm nomes significativos. Se seus identificadores forem códigos abstratos, consiere usar um dicionário de dados no lugar.

Passos

  1. Retornar informação de tabela

Primeiro, vamos extrair as definições de tabelas para um DataFrame pandas:

# Retrieve table definitions into a pandas DataFrame
table_def = get_table_definitions_array(cnx=cnx, schema='Aviation')
table_df = pd.DataFrame(data=table_def, columns=["col_def"])
table_df["id"] = table_df.index + 1
table_df

O DataFrame (table_df) deve se parecer com algo assim:

col_defid
0CREATE TABLE Aviation.Aircraft (\n Event bigi...1
1CREATE TABLE Aviation.Crew (\n Aircraft varch...2
2CREATE TABLE Aviation.Event (\n ID bigint NOT...3
  1. Separar as definições em documentos:

Em seguida, divida as definições de tabelas em documentos LangChain. Esse passo é crucial para lidar com grandes conjuntos de texto e extrair textos embutidos:

loader = DataFrameLoader(table_df, page_content_column="col_def")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=400, chunk_overlap=20, separator="\n")
tables_docs = text_splitter.split_documents(documents)
tables_docs

A lista resultante tables_docs contém documentos divididos com metadados, como o seguinte:

[Document(metadata={'id': 1}, page_content='CREATE TABLE Aviation.Aircraft (\n  Event bigint NOT NULL,\n  ID varchar NOT NULL,\n  ...'),
 Document(metadata={'id': 2}, page_content='CREATE TABLE Aviation.Crew (\n  Aircraft varchar NOT NULL,\n  ID varchar NOT NULL,\n  ...'),
 Document(metadata={'id': 3}, page_content='CREATE TABLE Aviation.Event (\n  ID bigint NOT NULL DEFAULT $i(^Aviation.EventD),\n  ...')]
  1. Extrair embutidos e guardar em IRIS

Agora, use a classe IRISVector do langchain-iris para extrair vetores embutidos e guardá-los:

tables_vector_store = IRISVector.from_documents(
    embedding=OpenAIEmbeddings(), 
    documents=tables_docs,
    connection_string=iris_conn_str,
    collection_name="sql_tables",
    pre_delete_collection=True
)

Nota: A bandeira pre_delete_collection é definida como True (verdadeiro) para propósitos de demonstração, para assegurar uma coleção nova em cada rodada de teste. Em um ambinte produtivo, essa bandeira geralmente deve ser definida como False (falso).

  1. Achar documentos relevantes

Com tabela de embutidos guardada, você agora pode consultar tabelas relevantes baseadas no input do usuário:

input_query = "List the first 2 manufacturers"
relevant_tables_docs = tables_vector_store.similarity_search(input_query, k=3)
relevant_tables_docs

Por exemplo, consultar por manufaturas pode retornar:

[Document(metadata={'id': 1}, page_content='GearType varchar,\n  LastInspectionDate timestamp,\n  ...'),
 Document(metadata={'id': 1}, page_content='AircraftModel varchar,\n  AircraftRegistrationClass varchar,\n  ...'),
 Document(metadata={'id': 3}, page_content='LocationSiteZipCode varchar,\n  LocationState varchar,\n  ...')]

Para os metadados, você pode ver que apenas o ID 1 da tabela (Aviation.Aircraft) é relevante, que linha com a consulta.

  1. Lidando com casos extremos

Apesar desta abordagem ser geralmente efetiva, pode não ser sempre perfeita. Por exemplo, consultar por áreas de queda pode retornar tabelas menos relevantes:

input_query = "List the top 10 most crash sites"
relevant_tables_docs = tables_vector_store.similarity_search(input_query, k=3)
relevant_tables_docs

Os resultados podem incluir:

[Document(metadata={'id': 3}, page_content='LocationSiteZipCode varchar,\n  LocationState varchar,\n  ...'),
 Document(metadata={'id': 3}, page_content='InjuriesGroundSerious integer,\n  InjuriesHighest varchar,\n  ...'),
 Document(metadata={'id': 1}, page_content='CREATE TABLE Aviation.Aircraft (\n  Event bigint NOT NULL,\n  ID varchar NOT NULL,\n  ...')]

Apesar de retornar a tabela correta Aviation.Event duas vezes, a tabela Aviation.Aircraft também pode aparecer, o que pode ser melhorado com filtros adicionais ou limitações. Isso está além do escopo deste exemplo e vai ser deixado para implementações futuras.

  1. Defina uma função para retornar tabelas relevantes

Para automatizar este processo, defina uma função para filtrar e retornar as tabelas relevantes baseado no input do usuário:

def get_relevant_tables(user_input, tables_vector_store, table_df):
    relevant_tables_docs = tables_vector_store.similarity_search(user_input)
    relevant_tables_docs_indices = [x.metadata["id"] for x in relevant_tables_docs]
    indices = table_df["id"].isin(relevant_tables_docs_indices)
    relevant_tables_array = [x for x in table_df[indices]["col_def"]]
    return relevant_tables_array

Essa função vai ajudar em retornar de maneira eficiente apenas as tabelas relevantes a enviar ao LLM, reduzindo o tamanho do prompt e melhorando a performance da consulta num geral.

Selecionando os exemplos mais relevantes (Few-Shot Prompting)

Ao trabalhar com modelos de linguagem (LLMs), fornecer exemplos relevantes ajuda a assegurar respostas precisas e contextualmente apropriadas. Esses exemplos, referidos como exemplos "few-shot", guiam o LLM para entender a estrutura e contexto das consultas que deve manusear. No nosso caso, precisamos popular a variável examples_value com um conjunto diverso de consultas SQL que cobrem um espectro vasto de sinitaxe IRIS SQL e as tabelas disponíveis na base de dados. Isso ajuda a prevenir que o LLM gere consultas incorretas ou irrelevantes.

Definindo Consultas de Exemplo

Abaixo, uma lista de queries de exemplo desenhadas para ilustrar várias operações SQL:

examples = [
    {"input": "List all aircrafts.", "query": "SELECT * FROM Aviation.Aircraft"},
    {"input": "Find all incidents for the aircraft with ID 'N12345'.", "query": "SELECT * FROM Aviation.Event WHERE EventId IN (SELECT EventId FROM Aviation.Aircraft WHERE ID = 'N12345')"},
    {"input": "List all incidents in the 'Commercial' operation type.", "query": "SELECT * FROM Aviation.Event WHERE EventId IN (SELECT EventId FROM Aviation.Aircraft WHERE OperationType = 'Commercial')"},
    {"input": "Ache o número total de incidentes.", "query": "SELECT COUNT(*) FROM Aviation.Event"},
    {"input": "Liste todos os incidentes que ocorreram no 'Canadá'.", "query": "SELECT * FROM Aviation.Event WHERE LocationCountry = 'Canada'"},
    {"input": "Quantos incidentes estão associados com a aeronave com AircraftKey 5?", "query": "SELECT COUNT(*) FROM Aviation.Aircraft WHERE AircraftKey = 5"},
    {"input": "Ache o número total de diferentes aeronaves envolvidas em incidentes.", "query": "SELECT COUNT(DISTINCT AircraftKey) FROM Aviation.Aircraft"},
    {"input": "Liste todos os incidentes que ocorreram após 5 PM.", "query": "SELECT * FROM Aviation.Event WHERE EventTime > 1700"},
    {"input": "Quem são os top 5 operadores por número de incidentes?", "query": "SELECT TOP 5 OperatorName, COUNT(*) AS IncidentCount FROM Aviation.Aircraft GROUP BY OperatorName ORDER BY IncidentCount DESC"},
    {"input": "Quais incidentes ocorreram no ano 2020?", "query": "SELECT * FROM Aviation.Event WHERE YEAR(EventDate) = '2020'"},
    {"input": "Qual foi o mês com mais incidentes no ano 2020?", "query": "SELECT TOP 1 MONTH(EventDate) EventMonth, COUNT(*) EventCount FROM Aviation.Event WHERE YEAR(EventDate) = '2020' GROUP BY MONTH(EventDate) ORDER BY EventCount DESC"},
    {"input": "Quantos membros de tripulação foram envolvidos em incidentes?", "query": "SELECT COUNT(*) FROM Aviation.Crew"},
    {"input": "Liste todos os incidentes com informações detalhadas da aeronave para os incidentes que ocorreram no ano 2012.", "query": "SELECT e.EventId, e.EventDate, a.AircraftManufacturer, a.AircraftModel, a.AircraftCategory FROM Aviation.Event e JOIN Aviation.Aircraft a ON e.EventId = a.EventId WHERE Year(e.EventDate) = 2012"},
    {"input": "Ache todos os incidentes onde houve mais de 5 feridos e inclua a fabricante da aeronave e modelo.", "query": "SELECT e.EventId, e.InjuriesTotal, a.AircraftManufacturer, a.AircraftModel FROM Aviation.Event e JOIN Aviation.Aircraft a ON e.EventId = a.EventId WHERE e.InjuriesTotal > 5"},
    {"input": "Liste todos os membros da tripulação envolvidos em incidentes com machucados sérios, junto da da data de incidente e localização.", "query": "SELECT c.CrewNumber AS 'Crew Number', c.Age, c.Sex AS Gender, e.EventDate AS 'Event Date', e.LocationCity AS 'Location City', e.LocationState AS 'Location State' FROM Aviation.Crew c JOIN Aviation.Event e ON c.EventId = e.EventId WHERE c.Injury = 'Serious'"}
]

[ Nota do tradutor: as frases foram traduzidas para fins de compreensão, mas os as informações de colunas nas frases deveriam idealmente ser deixadas em inglês para o interpretador melhor associar com as colunas na tabela, que estão em inglês. Segue um breve glossário: Aviation.Aircraft = Aviação.Aeronave key = chave month = mês count = contagem OpertationType = tipo de operação OperatorName = nome do operador LocationCountry = país de localização State = estado City = cidade Crew = Tripulação Injury = ferimento ]

Selecionando Exemplos Relevantes

Dada a lista de exemplos que vai sempre expandir, não é uma boa ideia fornecer todas elas ao LLM. Ao invés disso, vamos usar a Busca Vetorial IRIS com a classe SemanticSimilarityExampleSelector to identify the most relevant examples based on user prompts.

Defina o seletor de exemplo:

example_selector = SemanticSimilarityExampleSelector.from_examples(
    examples,
    OpenAIEmbeddings(),
    IRISVector,
    k=5,
    input_keys=["input"],
    connection_string=iris_conn_str,
    collection_name="sql_samples",
    pre_delete_collection=True
)

Nota: A bandeira pre_delete_collection é usada aqui para propósitos de demonstração para assegura uma coleção nova em cada rodada de teste. Em um ambiente produtivo, essa bandeira deve ser definida como False para evitar deleções desnecessárias.

Consulte o Seletor:

Para buscar os exemplos mais relevantes para uma dada entrada, use o seletor como se segue:

input_query = "Busque todos os eventos em 2010 informando o Event Id e date, location city e state, aircraft manufacturer e model."
relevant_examples = example_selector.select_examples({"input": input_query})

Os resultados devem parecer como algo assim:

[{'input': 'Liste todos os incidents com informações detalhadas sobre a Aircraft para os incidentes que ocorreram no year 2012.', 'query': 'SELECT e.EventId, e.EventDate, a.AircraftManufacturer, a.AircraftModel, a.AircraftCategory FROM Aviation.Event e JOIN Aviation.Aircraft a ON e.EventId = a.EventId WHERE Year(e.EventDate) = 2012'},
 {'input': "Busque todos os incidents para a Aircraft de ID 'N12345'.", 'query': "SELECT * FROM Aviation.Event WHERE EventId IN (SELECT EventId FROM Aviation.Aircraft WHERE ID = 'N12345')"},
 {'input': 'Ache todos os incidents onde houve mais de 5 injuries e inclua o aircraft manufacturer e model.', 'query': 'SELECT e.EventId, e.InjuriesTotal, a.AircraftManufacturer, a.AircraftModel FROM Aviation.Event e JOIN Aviation.Aircraft a ON e.EventId = a.EventId WHERE e.InjuriesTotal > 5'},
 {'input': 'Liste todas as aircrafts.', 'query': 'SELECT * FROM Aviation.Aircraft'},
 {'input': 'Ache o número total de aircrafts distintas envolvidas em incidents.', 'query': 'SELECT COUNT(DISTINCT AircraftKey) FROM Aviation.Aircraft'}]

Se você especificamente precisa de exemplos relacionados a quantidades, você pode procurar o seletor conforme:

input_query = "Qual foi o número de incidentes envolvendo a aircraft Boeing."
quantity_examples = example_selector.select_examples({"input": input_query})

A saída será:

[{'input': 'Quantos incidents estão associados à aircraft de AircraftKey 5?', 'query': 'SELECT COUNT(*) FROM Aviation.Aircraft WHERE AircraftKey = 5'},
 {'input': 'Busque o número total de aircrafts distintas envolvidas em incidents.', 'query': 'SELECT COUNT(DISTINCT AircraftKey) FROM Aviation.Aircraft'},
 {'input': 'Quantos membros de tripulação foram envolvidos em incidents?', 'query': 'SELECT COUNT(*) FROM Aviation.Crew'},
 {'input': 'Ache todos os incidents onde houve mais de 5 ferimentos e inclua a aircraft manufacturer e model.', 'query': 'SELECT e.EventId, e.InjuriesTotal, a.AircraftManufacturer, a.AircraftModel FROM Aviation.Event e JOIN Aviation.Aircraft a ON e.EventId = a.EventId WHERE e.InjuriesTotal > 5'},
 {'input': 'Liste todos os incidents com informação detalhada sobre as aircrafts para incidents que ocorreram no ano 2012.', 'query': 'SELECT e.EventId, e.EventDate, a.AircraftManufacturer, a.AircraftModel, a.AircraftCategory FROM Aviation.Event e JOIN Aviation.Aircraft a ON e.EventId = a.EventId WHERE Year(e.EventDate) = 2012'}]

A saída inclui exemplos que especificamente buscam contagens e quantidades.

Considerações futuras

Apesar do SemanticSimilarityExampleSelector ser poderoso, é importante nota que nem todos os exemplos serão perfeitos. Melhorias futuras podem incluir adição de filtros e limites para excluir resultados menos relevantes, assegurando que apenas os exemplos mais apropriados sejam fornecidos ao LLM.

Teste de precisão

Para acessar a performance do prompt e da geração de consultas SQL, precisamos definir e rodar uma série de testes. O objetivo é avaliar se a LLM gera de maneira ótima as consultas SQL baseadas em inputs de usuários e sem o uso dos few shots baseados em exemplos.

Função para gerar consultas SQL

Nós começamos definindo uma função que usa LLM para gerar consultas SQL baseadas no contexto providenciado, prompt, entrada do usuários e outros parâmetros:

def get_sql_from_text(context, prompt, user_input, use_few_shots, tables_vector_store, table_df, example_selector=None, example_prompt=None):
    relevant_tables = get_relevant_tables(user_input, tables_vector_store, table_df)
    context["table_info"] = "\n\n".join(relevant_tables)

    examples = example_selector.select_examples({"input": user_input}) if example_selector else []
    context["examples_value"] = "\n\n".join([
        example_prompt.invoke(x).to_string() for x in examples
    ])
    
    model = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
    output_parser = StrOutputParser()
    chain_model = prompt | model | output_parser
    
    response = chain_model.invoke({
        "top_k": context["top_k"],
        "table_info": context["table_info"],
        "examples_value": context["examples_value"],
        "input": user_input
    })
    return response

Execute o Prompt

Teste o prompt com e sem exemplos:

# Prompt execution **with** few shots
input = "Busque todos os eventos em 2010 informando o Event Id e date, location city e state, aircraft manufacturer e model."
response_with_few_shots = get_sql_from_text(
    context, 
    prompt, 
    user_input=input, 
    use_few_shots=True, 
    tables_vector_store=tables_vector_store, 
    table_df=table_df,
    example_selector=example_selector, 
    example_prompt=example_prompt,
)
print(response_with_few_shots)
SELECT e.EventId, e.EventDate, e.LocationCity, e.LocationState, a.AircraftManufacturer, a.AircraftModel
FROM Aviation.Event e
JOIN Aviation.Aircraft a ON e.EventId = a.EventId
WHERE Year(e.EventDate) = 2010
# Prompt execution **without** few shots
input = "Busque todos os eventos em 2010 informando o Event Id e date, location city e state, aircraft manufacturer e model."
response_with_no_few_shots = get_sql_from_text(
    context, 
    prompt, 
    user_input=input, 
    use_few_shots=False, 
    tables_vector_store=tables_vector_store, 
    table_df=table_df,
)
print(response_with_no_few_shots)
SELECT TOP 3 "EventId", "EventDate", "LocationCity", "LocationState", "AircraftManufacturer", "AircraftModel"
FROM Aviation.Event e
JOIN Aviation.Aircraft a ON e.ID = a.Event
WHERE e.EventDate >= '2010-01-01' AND e.EventDate < '2011-01-01'
Utility Functions for Testing

Para testar as queries geradas por SQL, definimos algumas funções úteis:

def execute_sql_query(cnx, query):
    try:
        cursor = cnx.cursor()
        cursor.execute(query)
        rows = cursor.fetchall()
        return rows
    except:
        print('Error running query:')
        print(query)
        print('-'*80)
    return None

def sql_result_equals(cnx, query, expected):
    rows = execute_sql_query(cnx, query)
    result = [set(row._asdict().values()) for row in rows or []]
    if result != expected and rows is not None:
        print('Result not as expected for query:')
        print(query)
        print('-'*80)
    return result == expected
# SQL test for prompt **with** few shots
print("SQL is OK" if not execute_sql_query(cnx, response_with_few_shots) is None else "SQL is not OK")
    SQL is OK
# SQL test for prompt **without** few shots
print("SQL is OK" if not execute_sql_query(cnx, response_with_no_few_shots) is None else "SQL is not OK")
    error on running query: 
    SELECT TOP 3 "EventId", "EventDate", "LocationCity", "LocationState", "AircraftManufacturer", "AircraftModel"
    FROM Aviation.Event e
    JOIN Aviation.Aircraft a ON e.ID = a.Event
    WHERE e.EventDate >= '2010-01-01' AND e.EventDate < '2011-01-01'
    --------------------------------------------------------------------------------
    SQL is not OK

Defina e Execute Testes

Defina um conjunto de casos de teste e rode eles:

tests = [{
    "input": "Quais são os 3 anos com mais eventos gravados?",
    "expected": [{128, 2003}, {122, 2007}, {117, 2005}]
},{
    "input": "Quantos incidentes envolveram a aircraft Boeing.",
    "expected": [{5}]
},{
    "input": "Quantos incidentes resultaram em fatalidades.",
    "expected": [{237}]
},{
    "input": "Liste o event Id e date e, crew number, age e gender para incidents que ocorreram em 2013.",
    "expected": [{1, datetime.datetime(2013, 3, 4, 11, 6), '20130305X71252', 59, 'M'},
                 {1, datetime.datetime(2013, 1, 1, 15, 0), '20130101X94035', 32, 'M'},
                 {2, datetime.datetime(2013, 1, 1, 15, 0), '20130101X94035', 35, 'M'},
                 {1, datetime.datetime(2013, 1, 12, 15, 0), '20130113X42535', 25, 'M'},
                 {2, datetime.datetime(2013, 1, 12, 15, 0), '20130113X42535', 34, 'M'},
                 {1, datetime.datetime(2013, 2, 1, 15, 0), '20130203X53401', 29, 'M'},
                 {1, datetime.datetime(2013, 2, 15, 15, 0), '20130218X70747', 27, 'M'},
                 {1, datetime.datetime(2013, 3, 2, 15, 0), '20130303X21011', 49, 'M'},
                 {1, datetime.datetime(2013, 3, 23, 13, 52), '20130326X85150', 'M', None}]
},{
    "input": "Ache o total de incidents ocorridos em United States.",
    "expected": [{1178}]
},{
    "input": "Liste todos as coordenadas de latitude e longitude de incidentes que resultaram em mais de 5 feridos em 2010.",
    "expected": [{-78.76833333333333, 43.25277777777778}]
},{
    "input": "Busque todos os incidentes em 2010 informando o Event Id e date, location city e state, aircraft manufacturer e model.",
    "expected": [
        {datetime.datetime(2010, 5, 20, 13, 43), '20100520X60222', 'CIRRUS DESIGN CORP', 'Farmingdale', 'New York', 'SR22'},
        {datetime.datetime(2010, 4, 11, 15, 0), '20100411X73253', 'CZECH AIRCRAFT WORKS SPOL SRO', 'Millbrook', 'New York', 'SPORTCRUISER'},
        {'108', datetime.datetime(2010, 1, 9, 12, 55), '20100111X41106', 'Bayport', 'New York', 'STINSON'},
        {datetime.datetime(2010, 8, 1, 14, 20), '20100801X85218', 'A185F', 'CESSNA', 'New York', 'Newfane'}
    ]
}]

Avaliação de precisão

Rode os testes e calcule a precisão:

def execute_tests(cnx, context, prompt, use_few_shots, tables_vector_store, table_df, example_selector, example_prompt):
    tests_generated_sql = [(x, get_sql_from_text(
            context, 
            prompt, 
            user_input=x['input'], 
            use_few_shots=use_few_shots, 
            tables_vector_store=tables_vector_store, 
            table_df=table_df,
            example_selector=example_selector if use_few_shots else None, 
            example_prompt=example_prompt if use_few_shots else None,
        )) for x in deepcopy(tests)]
    
    tests_sql_executions = [(x[0], sql_result_equals(cnx, x[1], x[0]['expected'])) 
                            for x in tests_generated_sql]
    
    accuracy = sum(1 for i in tests_sql_executions if i[1] == True) / len(tests_sql_executions)
    print(f'Accuracy: {accuracy}')
    print('-'*80)

Resultados

# Testes de precisão para prompts executados **sem** few shots
use_few_shots = False
execute_tests(
    cnx,
    context, 
    prompt, 
    use_few_shots, 
    tables_vector_store, 
    table_df, 
    example_selector, 
    example_prompt
)
    error on running query: 
    SELECT "EventDate", COUNT("EventId") as "TotalEvents"
    FROM Aviation.Event
    GROUP BY "EventDate"
    ORDER BY "TotalEvents" DESC
    TOP 3;
    --------------------------------------------------------------------------------
    error on running query: 
    SELECT "EventId", "EventDate", "C"."CrewNumber", "C"."Age", "C"."Sex"
    FROM "Aviation.Event" AS "E"
    JOIN "Aviation.Crew" AS "C" ON "E"."ID" = "C"."EventId"
    WHERE "E"."EventDate" >= '2013-01-01' AND "E"."EventDate" < '2014-01-01'
    --------------------------------------------------------------------------------
    result not expected for query: 
    SELECT TOP 3 "e"."EventId", "e"."EventDate", "e"."LocationCity", "e"."LocationState", "a"."AircraftManufacturer", "a"."AircraftModel"
    FROM "Aviation"."Event" AS "e"
    JOIN "Aviation"."Aircraft" AS "a" ON "e"."ID" = "a"."Event"
    WHERE "e"."EventDate" >= '2010-01-01' AND "e"."EventDate" < '2011-01-01'
    --------------------------------------------------------------------------------
    accuracy: 0.5714285714285714
    --------------------------------------------------------------------------------
# Testes de precisão para prompts executados **com** few shots
use_few_shots = True
execute_tests(
    cnx,
    context, 
    prompt, 
    use_few_shots, 
    tables_vector_store, 
    table_df, 
    example_selector, 
    example_prompt
)
    error on running query: 
    SELECT e.EventId, e.EventDate, e.LocationCity, e.LocationState, a.AircraftManufacturer, a.AircraftModel
    FROM Aviation.Event e
    JOIN Aviation.Aircraft a ON e.EventId = a.EventId
    WHERE Year(e.EventDate) = 2010 TOP 3
    --------------------------------------------------------------------------------
    accuracy: 0.8571428571428571
    --------------------------------------------------------------------------------

Conclusão

A acurácia das consultas SQL geradas com exemplos (few shots) é aproximadamente 49% maior se comparada àquelas geradas sem exemplos (85% vs. 57%).

References

0
0 63
Artigo Lealdo Flaminio · Jul. 31, 2024 6m read

Coleta de dados

Esse é um guia de instruções passo a passo para criar uma tarefa que coleta dados sobre a base InterSystems e as globais que contem (como se vê no App Open Exchange associado - encontre todo o código relacionado ali)

Termo de responsabilidade: Este software é meramente para fins de TESTE/DEMO. Este código não é suportado pela InterSystems como parte de nenhum produto. InterSystems o fornece como ferramenta de demonstração/teste para um produto e versão específicos. O usuário ou cliente é totalmente responsável pelo mantimento e teste deste software depois da entrega, e a InterSystems não terá nenhuma responsabilidade por erros ou mal uso deste código.

  1. Em primeiro lugar, importe o arquivo «DataCollection.xml» através do portal de administração e assegure que não há erros. Se houver, pode se tratar de uma questão de versões. Entre em contato com Ari Glikman em ari.glikman@intersystems.com para que os ajude a obter uma versão adequada para você. Ademais, assegure que está importando os dados no namespace cujos dados internos deseja coletar para sua inspeção.

  2. Uma vez finalizada a importação, você deve ver o pacote Sample/Muestra com vários subpacotes também.

image

Se um pacote de Sample/Muestra já está presente no seu servidor, então você deve ver os novos subpacotes junto com qualquer outra pasta que estava ali previamente.

  1. Agora é o momento de executar os testes unitários para assegurar-se que tudo funciona corretamente.

a. Crie uma pasta chamada Unit Tests que possa ser lida pelo seu Terminal InterSystems. Por exemplo, como eu tenho uma instalação local, cria uma pasta em meu disco C.

FolderStructure

b. Nesta pasta exportaremos agora a classee Sample.DBExpansion.Test.CaptureTest como arquivo xml.

image

c. No terminal, defina a global ^UnitTestRoot = “<< pasta onde está Unit Tests>>”.. Segundo o exemplo anterior, seria (não se esqueça que você deve estar no mesmo namespace onde você importou o pacote) C:\ (note que não é “C:\Unit Tests” !)

set ^UnitTestRoot = "C:\"

d. Por último, executamos os testes unitários. Faça isso executando a seguinte linha de código no terminal:

do ##class(Sample.DBExpansion.Test.TestManager).RunTest("Unit Tests", "/noload/nodelete")

Essencialmente estamos dizendo ao programa que execute todos os testes que se encontram na pasta C:\Unit Tests. Por hora, só temos um arquivo ali, que é o criado no passo 3.b.

A saída deve ser a seguinte

UnitTestOutput

Se não passarem todas os testes unitários, então o programa não está pronto para ser executado. Não continue com os passos seguintes até que obtenha uma saída que diga que todos os testes passaram.

  1. Felicidades! Agora é o momento de construir a tarefa. Para isso

a. Abra o portal de administração e vá a Operação de Sistema > Gerenciador de Tarefas > Nova tarefa

*Assegure que seu usuário tenha acesso ao namespace %SYS, se não a tarefa se executará, mas não coletará nenhum dado.

NewTask

Agora, há vários campos para completar acerca da tarefa que quer criar. Você deve escolher o namespace em que importou o pacote e dar um nome para a tarefa. Deverá dar uma descrição para futuras referências. O ideal é deixar a opção de verificação rápida sem marcar, isso significa que a tarefa se executará mais lentamente, mas coletará dados mais completos. Se demorar demais para executar (depende do tamanho que seja a base de dados e suas globais) , então talvez seja melhor marcar aqui e optar por uma tarefa mais rápida. HowManyGlobals indica quantos dados globais devem ser coletados: -1 indica todos os dados globais, e é a opção recomendada. Selecione Avançar, escolha com que frequência a tarefa deve ser executada e aperte em Finalizar.

Recording 2023-05-10 at 7 10 32 PM

b. Aparecerá o Calendário de Tarefas, onde poderá ver quando estão programadas todas as tarefas, incluindo a recém criada. Se, além disso, desejar executá-la agora, selecione Executar no lado direito.

Selecione o histórico de tarefas para assegurar que foi criada corretamente. Depois de executar a tarefa, você deve ver que também foi executada corretamente. Caso contrário, aparecerá um erro.

Esta tarefa criará duas tabelas:

Sample_DBExpansion_Data.DBAnalysisInfo.

Essa tabela vai armazenar dados sobre a própria base de dados. Nos referimos a isso como «metadatos». A informação que armazena pode ser vista na imagem que se segue. A FastFlag indicará a seleção escolhida em 4.a.

DBTable

Sample_DBExpansion_Data.GlobalAnalysisInfo

Essa irá conter a informação relativa às globais na base de dados. Observe que se há um nome de classe associado à global, o veremos aqui junto com seu tamanho. Por último, observe que o campo MetaDataID corresponde ao campo ID da tabela Sample_DBExpansion_Data.DBAnalysisInfo. Isso quer dizer que no momento em que se capturou a informação da base de dados, se capturou seu correspondente de informação global e compartilham esse número de identificação (são as globais da base de dados nesse momento). É uma forma de ver como evoluem no tempo as globais de uma base de dados e a própria base de dados.

GLOBALTABLE

  1. Em continuação, a interface de usuário um pouco mais bonita.

Recording_2023-05-23_at_2_03_45_PM_AdobeExpress

Mostra informação sobre a global e a base de dados que aparecem na tabela de uma maneira mais amigável. Há 3 gráficos: um que mostra o histórico dos dados, o segundo que mostra o histórico de tamanhos de uma global escolhida, seja através do menu ou de uma busca, e por último há uma visão geral de todos os tamanhos de globais. Na parte inferior, há uma tabela onde se introduz quantas globais se quer mostrar e as apresenta ordenadas por tamanho. A coluna %Change está realçada em amarelo para uma mudança mínima de tamanho, em verde para uma diminuição de tamanho e em vermelho para um aumento significativo de tamanho.

Você pode encontrar instruções passo a passo sobre como configurá-los aqui.

Se não te interessam os gráficos, continue com a análise de dados aqui.

Docker

Pré-requisitos

Assegure-se que tenha git e Docker desktop instalados.

Instalação

Clone/git pull o repositório em qualquer diretório local

$ git clone https://github.com/rcemper/PR_DataCollection.git
$ docker compose up -d && docker compose logs -f

Inicio do container Crie o diretório apropriado «/home/irisowner/dev/Unit Tests»
Defina ^UnitTestRoot = «/home/irisowner/dev/»

Para abrir o Terminal IRIS:

$ docker-compose exec iris iris session iris
USER>

ou utilizando WebTerminal.
http://localhost:42773/terminal/

Para acessar ao portal de administração do sistema IRIS http://localhost:42773/csp/sys/UtilHome.csp

Para acessar a UnitTestPortal http://localhost:42773/csp/sys/%25UnitTest.Portal.Indices.cls?$NAMESPACE=USUARIO

0
0 47
Artigo Heloisa Paiva · Jul. 30, 2024 3m read

Introdução

Talvez você já tenha reparado que a base HSAUDIT não tem uma tarefa de expurgo já configurada na maioria das versões do HealthShare, e isso pode ser um problema já que ela tem mapeamentos de globais em vários namespaces.

Se você notou que essa base está ocupando muito espaço em disco e está com dificuldades de limpá-la, esse artigo é para você.

Se você já tem uma ideia de como fazer isso, mas está utilizando uma versão mais antiga do HealthShare, onde a tarefa não existe pronta, ou o PurgeByDaysToKeep não existe, esse artigo também é para você.

Passo a passo

Criar a classe de tarefa

0
0 49
Artigo Danusa Calixto · Dez. 22, 2023 9m read

O Banco de Dados de Documentos do InterSystems IRIS (DocDB) oferece uma abordagem flexível e dinâmica de gestão dos dados de bancos de dados. O DocDB abraça o poder do JSON (JavaScript Object Notation), fornecendo um ambiente sem esquema para armazenar e recuperar dados.

É uma ferramenta poderosa que permite aos desenvolvedores ignorar um monte de código boilerplate na interação com aplicativos existentes, serialização, paginação e integração. O fluxo perfeito do DocDB com os serviços e as operações de Interoperability Rest possibilita um grande salto na produção e no gerenciamento de APIs.

Confira a documentação completa do DocDB aqui. No contexto deste artigo, mostrarei um caso de uso em que o DocDB é uma combinação perfeita.

Organizações que usam produtos da InterSystems como IRIS, Interoperability, TrakCare... geram constantemente requisitos novos e ágeis para o compartilhamento de dados com outros sistemas para consumo. A InterSystems oferece o adaptador JSON integrado para permitir que as classes persistentes sejam serializáveis em JSON no nível do registro. No entanto, reescrever seu aplicativo para estender o adaptador JSON não é uma tarefa fácil, e seus dados de interesse serão gerenciados sempre no nível do registro diretamente das classes do seu aplicativo. É aí que entra o DocDB, porque você pode criar consultas no código do seu aplicativo e despejá-las no DocDB como JSON, prontas para serem enviadas a apps para consumidores.

Aqui está um snippet executando qualquer procedimento armazenado do IRIS padrão de maneira genérica  e salvando a saída como registros no formato json.

//presumindo que os parâmetros existem como P1,P2,...Pn no contextoset queryData=$lb("queryclassname:queryname",<no of parameters>)
		set queryString=$lg(queryData,1)
		set paramCount=$lg(queryData,2)
		set args=$lb()
		for ix=1:1:paramCount{
			set var="P"_ix
			XECUTE ("(in,out) SET out=$g(in)", @var, .y)
			set$li(args,ix)=$s(y'="":""""_y_"""",1:""""_"""")
			}
		set resultSet=##class(%ResultSet).%New(queryString)
		XECUTE ("(in,out) set out=in.%Execute("_$lts(args)_")",resultSet,.scx)
		set sc=scx
		If$$$ISERR(sc) $$$ThrowStatus(sc)
		set columnNo=resultSet.GetColumnCount()
	<span class="hljs-keyword">While</span> resultSet.<span class="hljs-built_in">%Next</span>(.sc) {
		<span class="hljs-keyword">If</span> <span class="hljs-built_in">$$$ISERR</span>(sc) <span class="hljs-built_in">$$$ThrowStatus</span>(sc)
		
		<span class="hljs-keyword">set</span> row={}
		<span class="hljs-keyword">for</span> iz=<span class="hljs-number">1</span>:<span class="hljs-number">1</span>:columnNo{
			<span class="hljs-keyword">set</span> columnName=resultSet.GetColumnName(iz)
			<span class="hljs-keyword">do</span> row.<span class="hljs-built_in">%Set</span>(columnName,resultSet.GetDataByName(columnName))
		}
		<span class="hljs-keyword">set</span> sc=<span class="hljs-built_in">..AddRecordToReportResult</span>(ID,row)
		<span class="hljs-keyword">If</span> <span class="hljs-built_in">$$$ISERR</span>(sc) <span class="hljs-built_in">$$$ThrowStatus</span>(sc)
	}</code></pre>
ClassMethod AddRecordToReportResult(doc As%DynamicObject)As%Status {
    set sc=$$$OKtry {
		if (##class(%DocDB.Database).xNExists("PreparedReportDB")){
			set db=##class(%DocDB.Database).%GetDatabase("PreparedReportDB")
		} else {
			set db= ##class(%DocDB.Database).%CreateDatabase("PreparedReportDB")
		}
		set nwRecord=db.%SaveDocument(doc)
		do nwRecord.%Save(0)
		
		k nwRecord
	}catch err{
		set sc=$$$ADDSC(sc,$$$ERROR("5001",err.DisplayString()))
	}
	return sc
    
}

É isso. Seus dados, sejam quais forem, estão prontos para serem expostos a apps para consumidores.

Considerando o caso de uso de monitoramento de integrações, suas consultas verificarão o status da sua produção de interoperabilidade da InterSystems, os erros, alertas...

E os dados serão salvos em um DocDB em intervalos.

Class ProdEye.DataTask Extends%SYS.Task.Definition
{

Property IntervalMinutes As%Integer [ InitialExpression = 5 ]; Method OnTask() As%Status { try { set packageName=$P($classname(),".",1)

	<span class="hljs-keyword">set</span> targetDocument={}
	
	<span class="hljs-keyword">set</span> ZeroTimeStamp= <span class="hljs-built_in">$$HorologAddSecs</span><span class="hljs-symbol">^EnsUtil</span>(<span class="hljs-built_in">$ztimestamp</span>,-(<span class="hljs-built_in">..IntervalMinutes</span>*<span class="hljs-number">60</span>))
	
	<span class="hljs-keyword">set</span> targetDocument.TimeOfQuery=<span class="hljs-keyword">##class</span>(Ens.DataType.UTC).timeUTC()
	<span class="hljs-keyword">set</span> targetDocument.TimeOfQueryIdx=<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"getDateTimeUTCIdx"</span>)
	<span class="hljs-keyword">do</span> <span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetNameSpaceList"</span>)
	<span class="hljs-keyword">k</span> prodArray
	
	<span class="hljs-keyword">do</span> <span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetProductionsList"</span>,.prodArray)
	
	
	<span class="hljs-keyword">set</span> productionObjectList=[]
	
	<span class="hljs-keyword">set</span> currNameSpace=<span class="hljs-string">""</span>
	<span class="hljs-keyword">for</span>  {
		<span class="hljs-keyword">set</span> currNameSpace=<span class="hljs-built_in">$O</span>(prodArray(currNameSpace))
		<span class="hljs-keyword">quit</span>:currNameSpace=<span class="hljs-string">""</span>
		<span class="hljs-keyword">set</span> currProd=<span class="hljs-string">""</span>
		<span class="hljs-keyword">for</span>  {
			<span class="hljs-keyword">set</span> currProd=<span class="hljs-built_in">$O</span>(prodArray(currNameSpace,currProd))
			<span class="hljs-keyword">quit</span>:currProd=<span class="hljs-string">""</span>
			<span class="hljs-keyword">set</span> newProdData=<span class="hljs-built_in">$g</span>(prodArray(currNameSpace,currProd))
			<span class="hljs-keyword">set</span> newProd=<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Data.Production"</span>,<span class="hljs-string">"%New"</span>,currProd,<span class="hljs-built_in">$lg</span>(newProdData,<span class="hljs-number">1</span>),<span class="hljs-built_in">$lg</span>(newProdData,<span class="hljs-number">2</span>))
			
			<span class="hljs-keyword">k</span> compArray
			<span class="hljs-keyword">do</span> <span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetComponentListByProd"</span>,.compArray,currProd,currNameSpace)
			
			<span class="hljs-keyword">set</span> components=<span class="hljs-string">""</span>
			<span class="hljs-keyword">set</span> currComp=<span class="hljs-string">""</span>
			<span class="hljs-keyword">for</span>  {
				<span class="hljs-keyword">set</span> currComp=<span class="hljs-built_in">$O</span>(compArray(currProd,currComp))
				<span class="hljs-keyword">quit</span>:currComp=<span class="hljs-string">""</span>
				<span class="hljs-keyword">set</span> newComp=<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Data.ProductionConfigItem"</span>,<span class="hljs-string">"%New"</span>,currComp,<span class="hljs-built_in">$g</span>(compArray(currProd,currComp)))
				<span class="hljs-keyword">set</span> compId=<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetComponentId"</span>,currComp,currProd,currNameSpace)
				<span class="hljs-keyword">set</span> newComp.Type= <span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetComponentType"</span>,compId,currNameSpace)
				<span class="hljs-keyword">set</span> newComp.QueueSize=<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetComponentQueueData"</span>,currComp,currNameSpace)
				
				<span class="hljs-keyword">set</span> MessageStats=<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetComponentMessageCountAndAvg"</span>,currComp,ZeroTimeStamp,currNameSpace)
				<span class="hljs-keyword">set</span>:<span class="hljs-built_in">$lv</span>(MessageStats) newComp.MessageCount=<span class="hljs-built_in">$lg</span>(MessageStats,<span class="hljs-number">1</span>)
				<span class="hljs-keyword">set</span>:<span class="hljs-built_in">$lv</span>(MessageStats) newComp.MessageAVGProcessingMilliseconds=<span class="hljs-built_in">$lg</span>(MessageStats,<span class="hljs-number">2</span>)
				
				<span class="hljs-keyword">set</span> newComp.JobsStatus=<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Data.JobStatus"</span>,<span class="hljs-string">"BuildPropertyFromList"</span>,<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetComponentJobs"</span>,currComp,currNameSpace))
				<span class="hljs-keyword">set</span> newComp.Errors=<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Data.Log"</span>,<span class="hljs-string">"BuildPropertyFromList"</span>,<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetComponentErrors"</span>,currComp,ZeroTimeStamp,currNameSpace))
				<span class="hljs-keyword">set</span> newComp.Warnings=<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Data.Log"</span>,<span class="hljs-string">"BuildPropertyFromList"</span>,<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetComponentWarnings"</span>,currComp,ZeroTimeStamp,currNameSpace))
				<span class="hljs-keyword">set</span> newComp.Alerts=<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Data.Log"</span>,<span class="hljs-string">"BuildPropertyFromList"</span>,<span class="hljs-built_in">$classmethod</span>(packageName_<span class="hljs-string">".Query"</span>,<span class="hljs-string">"GetComponentAlerts"</span>,currComp,ZeroTimeStamp,currNameSpace))
				
				<span class="hljs-keyword">do</span> newProd.Components.Insert(newComp)
			}
			
			
			<span class="hljs-keyword">set</span> newProdJSONStr=<span class="hljs-string">""</span>
			<span class="hljs-keyword">do</span> newProd.<span class="hljs-built_in">%JSONExportToString</span>(.newProdJSONStr)
			<span class="hljs-keyword">set</span> newProdJSON={}.<span class="hljs-built_in">%FromJSON</span>(newProdJSONStr)
			<span class="hljs-keyword">do</span>:newProdJSON'=<span class="hljs-string">""</span> productionObjectList.<span class="hljs-built_in">%Push</span>(newProdJSON)
			}
		}
	
	<span class="hljs-keyword">do</span> targetDocument.<span class="hljs-built_in">%Set</span>(<span class="hljs-string">"ProductionList"</span>,productionObjectList)
	<span class="hljs-keyword">if</span> (<span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%DocDB.Database</span>).xNExists(packageName_<span class="hljs-string">".DB.ProdEyeDocument"</span>)){
		<span class="hljs-keyword">set</span> db=<span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%DocDB.Database</span>).<span class="hljs-built_in">%GetDatabase</span>(packageName_<span class="hljs-string">".DB.ProdEyeDocument"</span>)
	} <span class="hljs-keyword">else</span> {
		<span class="hljs-keyword">set</span> db= <span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%DocDB.Database</span>).<span class="hljs-built_in">%CreateDatabase</span>(<span class="hljs-string">"ProdEye.DB.ProdEyeDocument"</span>)
		<span class="hljs-keyword">do</span> db.<span class="hljs-built_in">%CreateProperty</span>(<span class="hljs-string">"TimeOfQueryIdx"</span>,<span class="hljs-string">"%Integer"</span>,<span class="hljs-string">"$.TimeOFQueryIdx"</span>,<span class="hljs-number">0</span>)
		}
	<span class="hljs-keyword">set</span> nwRecord=db.<span class="hljs-built_in">%SaveDocument</span>(targetDocument)
	
	<span class="hljs-keyword">if</span> <span class="hljs-built_in">$$$ISERR</span>(nwRecord){<span class="hljs-built_in">$$$ThrowStatus</span>(nwRecord)}
	
	<span class="hljs-keyword">set</span> nwRecord.ProfileName=<span class="hljs-built_in">$get</span>(<span class="hljs-symbol">^ProdEyeProfileName</span>(<span class="hljs-number">0</span>))
	<span class="hljs-keyword">set</span> nwRecord.TimeOfQueryIdx=targetDocument.TimeOfQueryIdx
	<span class="hljs-keyword">do</span> nwRecord.<span class="hljs-built_in">%Save</span>()
	
	<span class="hljs-keyword">return</span> <span class="hljs-built_in">$$$OK</span>
} <span class="hljs-keyword">catch</span> error {
	<span class="hljs-keyword">do</span> BACK<span class="hljs-symbol">^%ETN</span>
	<span class="hljs-keyword">return</span> <span class="hljs-built_in">$$$ERROR</span>(<span class="hljs-string">"5001"</span>,error.AsStatus())
	}

}

}

agora, qualquer aplicativo externo para consumidores pode buscar os dados para verificar o status da produção, alertas, erros e avisos usando um serviço REST simples da InterSystems conforme a seguir

Include Ensemble

Class ProdEye.Prod.ProdEyeRest Extends EnsLib.REST.Service {

Property PageSize As%Integer [ InitialExpression = 10 ];Property TokenValidationURL As%String;Parameter SETTINGS = "PageSize,TokenValidationURL"; XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ] { <Routes> <Route Url="/getdata" Method="POST" Call="GetData"/> </Routes> }

Method GetData(pInput As%Library.AbstractStream, Output poutput As%Stream) As%Status { quit:'$IsObject(pInput) $$$OKquit:(pInput.SizeGet()=0) $$$OKset paramsObj={}.%FromJSON(pInput.Read()) set cutoff=paramsObj.cutoff set authorisation=paramsObj.Authorisation set profilename=paramsObj.profilename

<span class="hljs-built_in">$$$TRACE</span>(<span class="hljs-built_in">..Adapter</span>.IOAddr_<span class="hljs-string">" Profile "</span>_profilename_<span class="hljs-string">" cutoff parameter: "</span>_paramsObj.<span class="hljs-built_in">%ToJSON</span>())

<span class="hljs-keyword">if</span> ('<span class="hljs-built_in">..Authorise</span>(authorisation,<span class="hljs-built_in">..TokenValidationURL</span>)){
	<span class="hljs-keyword">do</span> poutput.<span class="hljs-keyword">Write</span>(<span class="hljs-string">"{""Error"":""Invalid Credentials""}"</span>)
	<span class="hljs-keyword">do</span> <span class="hljs-built_in">..ReportHttpStatusCode</span>(<span class="hljs-number">403</span>)
	 <span class="hljs-keyword">return</span> <span class="hljs-built_in">$$$OK</span>
}

<span class="hljs-keyword">if</span> ('<span class="hljs-built_in">..ValidateCutoff</span>(cutoff)){
	<span class="hljs-keyword">do</span> poutput.<span class="hljs-keyword">Write</span>(<span class="hljs-string">"{""Error"":""Invalid Request Parameters""}"</span>)
	<span class="hljs-keyword">do</span> <span class="hljs-built_in">..ReportHttpStatusCode</span>(<span class="hljs-number">400</span>)
	 <span class="hljs-keyword">return</span> <span class="hljs-built_in">$$$OK</span>
}


<span class="hljs-keyword">try</span>{
	<span class="hljs-keyword">set</span> packageName=<span class="hljs-built_in">$P</span>(<span class="hljs-built_in">$classname</span>(),<span class="hljs-string">"."</span>,<span class="hljs-number">1</span>)
	<span class="hljs-keyword">SET</span> db = <span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%DocDB.Database</span>).<span class="hljs-built_in">%GetDatabase</span>(packageName_<span class="hljs-string">".DB.ProdEyeDocument"</span>)
	<span class="hljs-keyword">set</span> restriction=[]
	<span class="hljs-keyword">do</span> restriction.<span class="hljs-built_in">%Push</span>(<span class="hljs-string">"TimeOfQueryIdx"</span>)
	<span class="hljs-keyword">do</span> restriction.<span class="hljs-built_in">%Push</span>(cutoff)
	<span class="hljs-keyword">do</span> restriction.<span class="hljs-built_in">%Push</span>(<span class="hljs-string">"&gt;"</span>)
	
	<span class="hljs-keyword">do</span> restriction.<span class="hljs-built_in">%Push</span>(<span class="hljs-string">"ProfileName"</span>)
	<span class="hljs-keyword">do</span> restriction.<span class="hljs-built_in">%Push</span>(profilename)
	<span class="hljs-keyword">do</span> restriction.<span class="hljs-built_in">%Push</span>(<span class="hljs-string">"="</span>)
	
	<span class="hljs-keyword">SET</span> result = db.<span class="hljs-built_in">%FindDocuments</span>(restriction)
	
	<span class="hljs-keyword">if</span> ((<span class="hljs-built_in">$IsObject</span>(result))&amp;&amp;(<span class="hljs-built_in">$Isobject</span>(result.content))){
		<span class="hljs-keyword">set</span> resultPage={}
		<span class="hljs-keyword">set</span> resultPage.Next=<span class="hljs-number">0</span>
		<span class="hljs-keyword">set</span> resultList=[]
		
		<span class="hljs-keyword">set</span> iter=result.content.<span class="hljs-built_in">%GetIterator</span>()
		<span class="hljs-keyword">for</span> dx=<span class="hljs-number">1</span>:<span class="hljs-number">1</span>:<span class="hljs-built_in">..PageSize</span>{
			<span class="hljs-keyword">set</span> resultItem=iter.<span class="hljs-built_in">%GetNext</span>(.key,.resultItemvalue)
			<span class="hljs-keyword">if</span> <span class="hljs-built_in">$IsObject</span>(resultItemvalue){
				<span class="hljs-keyword">set</span> resultItemvalue={}.<span class="hljs-built_in">%FromJSON</span>(resultItemvalue.<span class="hljs-built_in">%Doc</span>)
				<span class="hljs-keyword">do</span> resultList.<span class="hljs-built_in">%Push</span>(resultItemvalue)
				<span class="hljs-keyword">set</span>:dx&gt;<span class="hljs-number">1</span> resultPage.Next=resultItemvalue.TimeOfQueryIdx
			}
			}
	<span class="hljs-keyword">set</span> resultPage.content=resultList
	
	
	<span class="hljs-keyword">do</span> poutput.<span class="hljs-keyword">Write</span>(resultPage.<span class="hljs-built_in">%ToJSON</span>())
	}<span class="hljs-keyword">else</span> {
		<span class="hljs-keyword">Throw</span> <span class="hljs-built_in">$$$ERROR</span>(<span class="hljs-string">"5001"</span>,<span class="hljs-string">"Error During Processing Data"</span>)
		}
} <span class="hljs-keyword">catch</span> error {
	<span class="hljs-keyword">do</span> poutput.<span class="hljs-keyword">Write</span>(<span class="hljs-string">"{""Error"":""Error During Processing Data : """</span>_error.AsSystemError()_<span class="hljs-string">""" ""}"</span>)
	<span class="hljs-keyword">do</span> <span class="hljs-built_in">..ReportHttpStatusCode</span>(<span class="hljs-number">500</span>)
	}

<span class="hljs-keyword">return</span> <span class="hljs-built_in">$$$OK</span>

}

ClassMethod ValidateCutoff(val As%String) As%Boolean { set sc=1quit:+val<=00quit:$l(+val)<50set valdt=$E(val,1,5)","$E(val,6,10)

<span class="hljs-keyword">try</span> {
	<span class="hljs-keyword">set</span> date=<span class="hljs-built_in">$zdt</span>(valdt)
	
}<span class="hljs-keyword">catch</span> err{
		
		<span class="hljs-keyword">set</span> sc=<span class="hljs-number">0</span>
	}

<span class="hljs-keyword">return</span> sc

}

ClassMethod Authorise(val As%String, TokenValidationURL As%String) As%Boolean { quit:$g(val)=""0if (TokenValidationURL=""){ set type=$P(val," ",1) set type=$zstrip($zstrip(type,"*c"),"<=>w") quit:$ZCVT(type,"L")'="basic"0set userpass=$P(val," ",2) set userpassDecoded=$system.Encryption.Base64Decode(userpass)

	<span class="hljs-keyword">set</span> user=<span class="hljs-built_in">$P</span>(userpassDecoded,<span class="hljs-string">":"</span>,<span class="hljs-number">1</span>)
	<span class="hljs-keyword">set</span> user=<span class="hljs-built_in">$zstrip</span>(<span class="hljs-built_in">$zstrip</span>(user,<span class="hljs-string">"*c"</span>),<span class="hljs-string">"&lt;=&gt;w"</span>)
	<span class="hljs-keyword">set</span> pass=<span class="hljs-built_in">$P</span>(userpassDecoded,<span class="hljs-string">":"</span>,<span class="hljs-number">2</span>)
	<span class="hljs-keyword">set</span> pass=<span class="hljs-built_in">$zstrip</span>(<span class="hljs-built_in">$zstrip</span>(pass,<span class="hljs-string">"*c"</span>),<span class="hljs-string">"&lt;=&gt;w"</span>)
	
	<span class="hljs-keyword">set</span> prodeyeUser=<span class="hljs-keyword">##class</span>(Ens.Config.Credentials).GetValue(<span class="hljs-string">"ProdEyeUser"</span>,<span class="hljs-string">"Username"</span>)
	<span class="hljs-keyword">set</span> prodeyePass=<span class="hljs-keyword">##class</span>(Ens.Config.Credentials).GetValue(<span class="hljs-string">"ProdEyeUser"</span>,<span class="hljs-string">"Password"</span>)
	
	<span class="hljs-keyword">return</span> ((prodeyeUser=user)&amp;&amp;(prodeyePass=pass))
}<span class="hljs-keyword">elseif</span>(TokenValidationURL'=<span class="hljs-string">""</span>){
	<span class="hljs-keyword">set</span> prodeyeAuthUser=<span class="hljs-keyword">##class</span>(Ens.Config.Credentials).GetValue(<span class="hljs-string">"ProdEyeAuthUser"</span>,<span class="hljs-string">"Username"</span>)
	<span class="hljs-keyword">set</span> prodeyeAuthPass=<span class="hljs-keyword">##class</span>(Ens.Config.Credentials).GetValue(<span class="hljs-string">"ProdEyeAuthUser"</span>,<span class="hljs-string">"Password"</span>)
	
	<span class="hljs-keyword">set</span> tokenVerificationRequest=<span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%Net.HttpRequest</span>).<span class="hljs-built_in">%New</span>()
	<span class="hljs-keyword">do</span> tokenVerificationRequest.SetHeader(<span class="hljs-string">"content-type"</span>,<span class="hljs-string">"application/json"</span>)
	<span class="hljs-keyword">do</span> tokenVerificationRequest.SetHeader(<span class="hljs-string">"Authorisation"</span>,<span class="hljs-string">"BASIC "</span>_<span class="hljs-built_in">$system</span>.Encryption.Base64Encode(prodeyeAuthUser_<span class="hljs-string">":"</span>_prodeyeAuthPass))
	<span class="hljs-keyword">set</span> token=<span class="hljs-built_in">$P</span>(val,<span class="hljs-string">" "</span>,<span class="hljs-number">2</span>)
	<span class="hljs-keyword">set</span> data={}
	<span class="hljs-keyword">set</span> data.Token=token
	<span class="hljs-keyword">do</span> tokenVerificationRequest.EntityBody.<span class="hljs-keyword">Write</span>(data.<span class="hljs-built_in">%ToJSON</span>())
	<span class="hljs-keyword">do</span> tokenVerificationRequest.Post(TokenValidationURL)
	
	<span class="hljs-keyword">set</span> response=tokenVerificationRequest.HttpResponse
	<span class="hljs-keyword">if</span> (<span class="hljs-built_in">$IsObject</span>(response) &amp;&amp; <span class="hljs-built_in">$IsObject</span>(response.Data) &amp;&amp; response.StatusCode=<span class="hljs-number">200</span> ){
		<span class="hljs-keyword">set</span> message=<span class="hljs-string">""</span> <span class="hljs-keyword">while</span> 'response.Data.AtEnd {<span class="hljs-keyword">set</span> message=message_response.Data.<span class="hljs-keyword">Read</span>(,.tSC) <span class="hljs-keyword">if</span> 'tSC <span class="hljs-keyword">quit</span>}
		<span class="hljs-keyword">set</span> responseMessage={}.<span class="hljs-built_in">%FromJSON</span>(message)
		<span class="hljs-keyword">if</span> (responseMessage.<span class="hljs-built_in">%IsDefined</span>(<span class="hljs-string">"IsValid"</span>) &amp;&amp; (responseMessage.IsValid=<span class="hljs-string">"1"</span>)){
			<span class="hljs-keyword">return</span> <span class="hljs-number">1</span>
		}<span class="hljs-keyword">else</span>{
			<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>
				}
	}<span class="hljs-keyword">else</span>{
		<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>
			}
	}

}

}

Um exemplo real de um aplicativo de consumo do caso de uso acima está disponível aqui no Open Exchange. É um aplicativo móvel desenvolvido em Dart para o framework Flutter.

Além disso, o DocDB expõe a API direta sobre todas as tabelas de documentos, descritas em detalhes aqui

A vantagem da funcionalidade do DocDB é tornar o desenvolvimento de APIs para compartilhamento de informações entre sistemas orientado pelo foco do caso de uso, rastreando e padronizando toda a serialização, staging e integração de dados ao mesmo tempo.

0
0 104
Artigo Danusa Calixto · Nov. 28, 2023 2m read

Neste artigo, demonstro como criar uma coluna de tabela (antes chamada de "propriedades") com suas classes datatype personalizadas ao usar a DDL definida pelo usuário. As propriedades são um membro fundamental da definição de classe persistente. Datatypes são essenciais para definir os tipos de valores armazenados em uma coluna da tabela. Em geral, os nomes de datatype do SQL diferem dos datatypes da InterSystems, como VARCHAR = %String. Você tem a capacidade de criar ou modificar uma tabela ao usar esses datatypes. De fato, você está criando tabelas pela DDL e já tem suas próprias classes de datatype definidas. Esses datatypes devem ser usados ao executar create/alter na sua definição de classe, em vez dos datatypes padrão da InterSystems. Eles são bastante fáceis de usar ao seguir os passos abaixo

Faça login no portal de gerenciamento. Acesse Sistema > Configuração > Mapeamentos de DDL definidos pelo usuário. Crie um novo mapeamento de DDL definido pelo usuário. Adicione o nome do datatype padrão do SQL que será usado nas consultas SQL. Incorpore sua própria classe datatype no Datatype. Pressione o botão Salvar. Tudo pronto para usar na DDL!

Crie/use sua classe datatype

Class Samples.DT.BoolYN [ ClassType = datatype ]
{
/// A implementação está pronta
}

Execute a consulta SQL. - O datatype de DDL definido pelo usuário está no campo IsActive

   CREATE TABLE Employees (
        FirstName VARCHAR(30),
        LastName VARCHAR(30),
        StartDate TIMESTAMP,
        IsActive BIT(%1)
    )

Depois que a consulta é executada. A definição da classe é criada com sua própria classe de datatype

/// Class Sample.Person Extends%Persistent [ ClassType = persistent, DdlAllowed, Final, Owner = {_SYSTEM}, ProcedureBlock, SqlRowIdPrivate, SqlTableName = Person ]
{

Property FirstName As%String(MAXLEN = 50) [ SqlColumnNumber = 2 ];Property LastName As%String(MAXLEN = 50) [ SqlColumnNumber = 3 ];Property StartDate As%Library.TimeStamp [ SqlColumnNumber = 4 ];Property IsActive As Samples.DT.BoolYN [ SqlColumnNumber = 5 ];Parameter USEEXTENTSET = 1;/// O Bitmap Extent Index é gerado automaticamente pela declaração CREATE TABLE da DDL. Não edite o SqlName desse índice. Index DDLBEIndex [ Extent, SqlName = "%%DDLBEIndex", Type = bitmap ]; }

 Você pode usar esses mesmos nomes da DDL definidos pelo usuário na execução da DDL de Datatype no InterSystems IRIS

CREATE TABLE Sample.Person (
            FirstName %String(MAXLEN=50),
            LastName %String(MAXLEN=50),
            StartDate %TimeStamp,
            IsActive BIT(%1)
        ) 
0
0 111
Artigo Davi Massaru Teixeira Muta · Maio 14, 2023 5m read

#O problema

Temos o seguinte cenário, você trabalha em um laboratório, que até então atendia apenas exames realizados em uma região geográfica especifica, porém dentro de um curto espaço de tempo, percebe que seu negócio está expandindo para outras regiões, a demanda pela entrega dos resultados dos exames passa a não ser mais suportada pelo servidor principal, quedas e lentidões devido a alta repentina de solicitações, passam a ser mais frequentes e seus clientes passam a reclamar da indisponibilidade do sistema, como lidar com essa situação ?

image

Obviamente sua aplicação precisa ter a infraestrutura aprimorada, caso esteja utilizando a plataforma de dados InterSystems IRIS/Caché, a utilização de ECP’s pode ser uma saída para o problema.

#ECP

ECP - “Enterprise Cache Protocol” protocolo com arquitetura de cache de dados distribuídos, permite distribuir dados e lógica de aplicativos de forma eficiente em vários sistemas de servidores.

Ao contrário de outras arquiteturas multicamadas, o ECP é uma opção de configuração, que não requer usar código especial ou técnicas de desenvolvimento para criar aplicativos de banco de dados distribuídos, fazendo com que diversos servidores executem a aplicação usando a mesma base de código, permitindo que os desenvolvedores se concentrem na funcionalidade central centrada no cliente, tornando o aplicativo mais simples de manter.

#Configuração ECP’s?

Para compreender a configuração de um E.C.P, é importante entender como os artefatos de código e dados são organizados dentro da plataforma InterSystems IRIS.

#Mapeamento de namespaces.

Namespace é uma unidade lógica de organização em InterSystems IRIS que permite a separação de objetos e recursos do sistema em grupos distintos. Tornando mais fácil a administração e o gerenciamento do sistema.

Cada Namespace é configurado para utilizar banco de dados de globais e rotinas, que é utilizado para armazenar e gerenciar os dados globais e objetos de rotinas.

image

- Banco de dados provedor de Globais:

O Banco de dados provedor de globais, é usado para armazenar e gerenciar os dados globais em um determinado namespace.

##- Banco de dados provedor de Rotinas: Rotinas são artefatos do banco que executam tarefas específicas no sistema, plataformas de dados InterSystems utilizando o provedor de rotinas como um banco de dados especializado para armazenar e gerenciar as rotinas de código em um namespace.

#Realizar os mapeamentos Para configurar o ECP (Enterprise Cache Protocol), é necessário seguir alguns passos simples. Primeiramente, é preciso instalar uma nova máquina com uma instância de InterSystems IRIS ou Cache. Em seguida, é necessário configurar os servidores de aplicação no servidor de dados e vice-versa, para que o ambas instâncias Intersystems possam se comunicar, podendo configurar e distinguir entre bancos de dados locais e remotos entre as instâncias.

• Banco de dados local: É o banco de dados que reside fisicamente na mesma máquina em que o banco IRIS/Caché está sendo executado, associado a uma instância InterSystmes, sendo acessado e gerenciado pela própria instância do IRIS no servidor local.

• Banco de dados remoto: Banco de dados que está localizado em um servidor separado, ou seja, em uma máquina diferente daquela onde o IRIS está sendo executado.

Em seguida, devemos configurar o E.C.P (novo servidor de aplicação) para utilizar os bancos de dados remotos, provenientes do servidor de dados principal (onde possui os seus apontamentos locais), com a possibilidade de organização do namespace apontar para os bancos de global (dados) e rotinas (código) remotos, seguindo a seguinte estrutura:

image

Ao configurar o Enterprise Cache Protocol (ECP) e o namespace no InterSystems IRIS com o uso de bancos de dados remotos, ocorre uma distribuição de tarefas e recursos entre o servidor de aplicação (onde está o ECP) e o servidor de dados (onde estão os bancos de dados locais).

#Rede de E.C.Ps:

No cenário de configuração de diversos E.C.P.s com bancos de dados remotos, os processos (JOBs), são executados no servidor de aplicação controlando o fluxo de trabalho e garantindo a escalabilidade e o balanceamento de carga.

No entanto, os dados e as rotinas são armazenados no servidor de dados, onde estão localizados os bancos de dados locais. Ele fornece o armazenamento centralizado para os dados e as rotinas utilizados pelos processos executados no servidor de aplicação.

Essa arquitetura distribuída permite que o processamento e o armazenamento sejam separados, essa configuração permite um ambiente distribuído eficiente, com recursos compartilhados.

image

Desta forma você pode escalar sua aplicação, para atender uma demanda que seu sistema necessita, sem a alteração de códigos de sua aplicação, a expansão do seu laboratório para outras regiões geográficas pode trazer desafios significativos em relação à capacidade e disponibilidade do sistema. No entanto, a utilização dos ECPs (Enterprise Cache Protocol) no InterSystems IRIS/Caché pode ser solução viável para lidar com essa situação. Ao implementar uma infraestrutura aprimorada e distribuída, é possível alcançar uma maior capacidade de processamento, melhorar o desempenho e garantir a disponibilidade dos resultados dos exames.

Os ECPs permitem uma distribuição eficiente da carga de trabalho, com processos sendo executados nos servidores de aplicação e os dados sendo armazenados nos servidores de dados.

Essa abordagem proporciona uma maior escalabilidade e balanceamento de carga, evitando quedas e lentidões causadas pelo aumento repentino na demanda. Além disso, a infraestrutura distribuída permite a centralização e o gerenciamento eficiente dos dados, facilitando a expansão para novas regiões sem comprometer a qualidade do serviço.

Ao adotar os ECPs no InterSystems IRIS/Caché, você estará preparando sua aplicação para suportar o crescimento e atender às demandas dos clientes em diferentes regiões geográficas. Essa solução proporciona maior escalabilidade e desempenho, permitindo que seu laboratório ofereça um serviço de qualidade, com resultados de exames entregues.

3
6 620
Artigo Miqueias Santos · Maio 17, 2023 30m read

Veremos a seguir como o InterSystems IRIS aliado com Machine Learning pode transformar para melhor a educação do Brasil e do mundo

image

. .

O video de apresentação:

Clique na imagem abaixo para ver o video de apresentação. [![Video de Apresentação](https://img.youtube.com/vi/QOY60kRkSnQ/maxresdefault.jpg)](https://www.youtube.com/watch?v=QOY60kRkSnQ) . .

Educação Integrada com InterSystems IRIS

A ideia é integrar a educação usando InterSystems IRIS para permitir a criação de uma plataforma completa para gestão, análise, melhoria e transformação da educação. Com o InterSystems IRIS, seria possível integrar dados de diferentes fontes, como informações sobre alunos, professores, diretores, escolas, faculdades, cursos, entre outros, em um único lugar.

Nós sabemos que a educação é um setor de extrema importância para a sociedade, e pode ser considerado um negócio lucrativo não só financeiramente, mas também em termos de desenvolvimento social e econômico, por isso escolhi este caso de negócio. A pricinpal abordagem tecnólogica usada aqui é o Machine Learning, pois a ideia é que ferramentas de IA sejam usadam para melhorar a educação humana e não o contrário.

O projeto envolve combinar InterSystems IRIS e Machine Learning, além de outras abordagens técnologicas para criar uma plataforma de educação completamente integrada, onde todas as instituições de ensino do país estaram ligadas a plataforma, para permitir a integração de milhares de dados educacionais, que seriam usados para se servir ferramentas de ensino, análise e gestão da educação de um jeito nunca visto antes, utilizando do Machine Learning para se prever problemas e apresentar soluções que seriam capazes de melhorar completamente o ensino do Brasil.

Usar e desenvolver ferramentas de IA para colaborar com a evolução humana, não para se aproveitar de suas fraquezas.

É um fato que tecnologias relacionadas à Inteligência Artificial estão em constante evolução, desta forma se torna cada vez mais necessário melhorar a eficiência da educação humana, para que humanos evoluam junto e não fiquem para trás. Sendo assim, em um mundo tão cheio de informações e conhecimento, precisamos de ferramentas poderosas de processamento de dados, integração e análise em tempo real, e é ai que entra o InterSystems IRIS.

Graças ao InterSystems IRIS podemos criar uma plataforma global de educação, integrar dados de diferentes fontes, executar análises em tempo real e fornecer insights acionáveis para tomada de decisão rápida e precisa. Poderemos usar diferentes abordagens tecnológicas em conjunto com o InterSystems IRIS, esta plataforma seria usada por escolas, faculdades e outras instituições de ensino, abrindo caminho para trazer a gamificação na sua forma máxima em todas as fases da educação, aumentando o engajamento das pessoas no ensino e na educação de qualidade.

Graças ao InterSystems IRIS e o Machine Learning podemos mudar a realidade de países como o Brasil, um país que sofre com uma educação de péssima qualidade há muitos anos, desta forma vamos criar uma plataforma colaborativa e integrada de educação, que vai salvar a educação do Brasil.

Arquitetura

A arquitetura (modelo lógico) da plataforma Educação Integrada InterSystems IRIS vai envolver combinar diferentes componentes tecnológicos para atender às necessidades específicas deste projeto. Em termos gerais, a plataforma tem a seguinte arquitetura:

InterSystems IRIS:

Nossa plataforma é construida em cima do InterSystems IRIS, o que facilita a criação de aplicativos habilitados para aprendizado de máquina de alto desempenho que conectam dados e silos de aplicativos.

Com ele vamos ter gerenciamento de banco de dados de alto desempenho, interoperabilidade e recursos de análise, todos integrados desde o início para acelerar e simplificar os aplicativos com uso intensivo de dados mais exigentes e integra-se perfeitamente a infraestrutura existente.

Front-end:

O front-end é construído usando o framework Angular, que vai permitir que se desenvolva uma interface amigável e intuitiva para os usuários finais da plataforma, incluindo professores, alunos, pais, diretores, empresas e funcionários públicos e privados e etc.

Back-end:

O back-end é construído usando InterSystems API Manager e ObjectScript. Sabendo que O API Manager usa contêineres, precisaremos trabalhar com contêineres e Docker também.

Observação: O InterSystems API Manager (IAM) é um componente independente que a InterSystems fornece para uso com os produtos InterSystems IRIS. Ele permite que se monitore, controle e administre o tráfego de API baseado em HTTP, o InterSystems API Manager (IAM) permite que se aproveite ao máximo os microsserviços e APIs que são expostos ou consumidos por aplicativos InterSystems IRIS.

O InterSystems API Manager é uma solução de gerenciamento de API que oferece recursos de segurança, autenticação, autorização e monitoramento de API em tempo real, enquanto o ObjectScript é uma linguagem de programação multi-paradigma que é usada para desenvolver aplicativos para a plataforma InterSystems IRIS. No caso também podemos trazer mais do Machine Learning caso haja necessidades especifícas, pois o InterSystems IRIS também oferece suporte integrado para Python e outras linguagens externas.

O API Manager fornece uma interface para gerenciar, autenticar e monitorar as APIs desenvolvidas em ObjectScript ou em outras linguagens, já o ObjectScript fornece a lógica de negócios para as APIs. Quando uma solicitação é feita a uma API gerenciada pelo API Manager, o API Manager encaminha a solicitação para o serviço ObjectScript correspondente. Depois que o serviço processa a solicitação, ele retorna uma resposta ao API Manager, que por sua vez manda a resposta de volta ao cliente. Isso permite que o ObjectScript se concentre na lógica de negócios, enquanto o API Manager gerencia a autenticação, autorização, segurança e monitoramento de API. Além de ser excelente para definir os consumidores para alunos, professores, pais e etc; Eles representam “aplicativos diferentes” que farão chamadas de API para o API Manager.

Banco de dados:

O banco de dados é hospedado no InterSystems IRIS. A plataforma de dados InterSystems IRIS fornece uma arquitetura multimodelo que permite usar o modelo de dados que melhor se adapta a cada tarefa ( relacional, de objeto ou até mesmo acesso direto/nativo ) tudo acessível por meio do idioma escolhido. que oferece alta escalabilidade, segurança e disponibilidade para o banco de dados.

Hoje o InterSystems IRIS também permite a integração direta com o Kafka, o que nos permite ter aplicativos de streaming em tempo real de alto desempenho.

Machine Learning:

Nossa plataforma também utiliza o InterSystems IntegrateML, que oferece recursos avançados de Machine Learning para análise de dados e previsão de tendências. IntegratedML é um novo recurso do InterSystems IRIS que permite que os desenvolvedores SQL desenvolvam facilmente modelos de aprendizado de máquina com apenas alguns comandos semelhantes a SQL. Os modelos de aprendizado de máquina podem ser integrados perfeitamente em aplicativos e produções para serem executados em tempo real em resposta a eventos e transações. Desta forma vamos poder oferecer para todos os usuários da plataforma uma ferramenta poderosa de IA para colaborar com o progresso da evolução humana, oferecendo análises de desempenho, dicas e permitindo que se ofereça uma atenção individual para as dificuldades em particular de cada indivíduo.

IoT:

A plataforma é integrada com sensores IoT, para rastrear o desempenho dos alunos em tempo real. Isso é usado para análise, gamificação, previsões do IntegrateML, planos de segurança, melhora da experiência dos alunos, monitoramento de energia, monitorar temperatura e umidade, gerenciar presença, monitorar o uso das instalações e etc. Como nosso modelo de comunicação terá uma arquitetura centralizada, teremos várias instâncias InterSystems IRIS, desta forma cada instituição terá sua própria infraestrutura IoT de forma independente.

Blockchain:

A plataforma poderá também ser integrada com a tecnologia Blockchain para garantir a segurança dos dados dos usuários e a transparência em todo o sistema educacional. A blockchain poderá, será utilizada para garantir a integridade e a segurança dos registros e transações realizadas pelos usuários, como alunos, professores, pais e outros. Por exemplo a blockchain poderá ser utilizada para registrar a emissão de diplomas e certificados digitais, garantindo a autenticidade dos documentos e prevenindo fraudes.

Com essa arquitetura vamos poder combinar diferentes tecnologias e abordagens tecnológicas para fornecer uma plataforma robusta e escalável para gerenciamento, análise, controle e melhoria da educação no país. Ainda poderemos integra-la com outras plataformas e serviços externos, como empresas e o governo federal, para permitir que a plataforma Educação Integrada InterSystems IRIS ofereça uma experiência de usuário ainda mais abrangente e enriquecedora.

image

Observação: Pode haver a necessidade de se trabalhar com outras linguagens e tecnologias, por isso na imagem abaixo podemos ter uma ideia melhor do que é possivel com InterSystems IRIS

image

Funcionalidades do InterSystems IRIS que são de extrema importância para o funcionamento desta plataforma:

  1. Ferramentas de colaboração: Algo muito importante é o trabalho em equipe, que é crucial para um projeto como esse. E como o InterSystems IRIS oferece várias ferramentas de colaboração, como mensagens, notificações e bate-papo, que permitem que as equipes trabalhem juntas de maneira mais eficiente seria possível com toda certeza desenvolver um projeto tão grande como este.

  2. Armazenamento de dados: Precisamos de um armazenamento de dados muito bom e como o InterSystems IRIS tem um armazenamento de dados de alto desempenho e escalável que permite armazenar dados de várias fontes em um único local teremos o necessário, com toda certeza.

  3. Acesso a dados em tempo real: O setor da Educação demanda uma tomada de decisão muito precisa e inteligente. Desta forma temos aqui mais um motivo para escolher o InterSystems IRIS, pois ele nos permite ter o acesso a dados em tempo real de várias fontes, incluindo dados estruturados e não estruturados. Isso permite se tomar decisões informadas em tempo real com base em insights valiosos.

  4. Integração com outros sistemas: Não pode parar, não pode perder, precisa integrar. O InterSystems IRIS pode ser facilmente integrado com sistemas de terceiros. Desta forma as instituições vão poder estender soluções existentes e aumentem sua eficiência operacional. O que é muito importante, pois hoje já temos muitos sistemas em uso no setor educacional, então poderemos aumentar a eficiência de grande parte deles e/ou liberar mais informações valiosas de tomada de decisão.

  5. Monitoramento e gerenciamento de desempenho: O MEC e as instituições vão precisar de ferramentas de monitoramento e gerenciamento de desempenho que permitem que se monitore e otimize o desempenho dos sistemas em tempo real, o que é outra funcionalidade do InterSystems IRIS.

  6. Desenvolvimento de aplicativos móveis: Uma das ideias é que pais possam acompanhar o desempenho de seus filhos em qualquer lugar, usando um smartphone por exemplo e como o InterSystems IRIS permite o desenvolvimento de aplicativos móveis de alta qualidade e seguros que podem ser facilmente integrados com outros sistemas, nossa plataforma poderá oferecer aplicativos móveis para todos: pais, professores, alunos e outros.

  7. Segurança avançada: Precisamos de total segurança em uma platforma como esta, é um setor muito importante. InterSystems IRIS oferece recursos de segurança avançados, como autenticação, autorização e criptografia de dados, garantindo que os dados sejam mantidos seguros.

  8. Escalabilidade: Nossa plataforma precisa ser altamente escalável, ou seja, tem que ter condições para crescer de forma uniforme ou para suportar um aumento de carga e ser capaz de lidar com grandes volumes de dados e tráfego de aplicativos, permitindo que a plataforma cresça e se adapte às necessidades em constante mudança do setor educacional. Algo que é totalmente possível no InterSystems IRIS.

  9. Processamento de fluxo de dados em tempo real: O InterSystems IRIS permite o processamento de fluxo de dados em tempo real, o que é ideal para este projeto que exige análise de dados em tempo real, esta plataforma seria uma grande ferramenta de mudança, e teria grande importância na sociedade, além de trabalhar com muitas tecnologias e processar grandes quantidades de dados, então com toda certeza esta capacidade do InterSystems IRIS é crucial.

  10. Business Intelligence (BI) e análise avançada: O InterSystems IRIS oferece recursos avançados de BI e análise, permitindo que a plataforma crie relatórios, dashboards e análises avançadas de seus dados. Isso ajudaria as instituições e orgãos responsáveis a tomar decisões informadas com base em insights valiosos.

  11. Integração de sistemas legados: O InterSystems IRIS oferece recursos de integração que permitem que as instituições integrem facilmente seus sistemas legados com sistemas modernos e em nuvem, aumentando a eficiência operacional e reduzindo custos.

  12. Desenvolvimento de aplicações web: Como vimos na arquitetura, a principal tecnologia de front-end escolhida foi o Angular e apesar de no diagrama apresentarmos uma arquitetura de um cliente web externo ao servidor, também podemos ter um cliente web servido pelo InterSystems IRIS. O InterSystems IRIS permite o desenvolvimento de aplicações web de alta qualidade e seguras, utilizando tecnologias modernas como Angular, React, Vue.js e outros.

  13. Automação de processos empresariais: Educação também é negócio, um negócio lucrativo, desta forma serão necessários recursos de automação de processos empresariais (BPM) que permitem que as instituições automatizem e gerenciem seus processos de negócios de forma mais eficiente. O InterSystems IRIS oferece!

  14. Suporte para múltiplos idiomas e regiões: O InterSystems IRIS suporta múltiplos idiomas e regiões, permitindo que a plataforma atenda clientes e usuários em todo o mundo.

  15. Regras de Negócios(Business Rules): Com esta funcionalidade, o InterSystems IRIS permite que usuários não técnicos alterem o comportamento dos processos de negócios em pontos de decisão específicos. Sendo possível alterar a lógica da regra instantaneamente, usando o editor de regras no portal de gerenciamento. Imagine que uma instituição de ensino que está em todo o Brasil acaba de lançar um programa de bolsas de estudo, mas cada "filial" desta instituição tem seus próprios critérios de aceitação de alunos, com as regras de negócios suportamos essa divisão de responsabilidade. Portanto, é possível que analistas de negócios em vários locais regionais executem o Editor de Regras para modificar suas cópias da regra para fornecer diferentes critérios específicos apropriados para suas localidades.

  16. Encryption (Criptografia): Uma plataforma como esta vai lidar com muitos dados valiosos, por isso precisamos protege-lá contra acesso não autorizado a dados em disco, por isso está funcionalidade do InterSystems IRIS de criptografia é muito importante. O InterSystems IRIS fornece criptografia de chave gerenciada , um conjunto de tecnologias que protegem os dados em repouso.

  17. Mirroring and High Availability: Outra funcionalidade muito importante do InterSystems IRIS é o espelhamento e alta disponibilidade, está pode ser considerada uma plataforma de missão crítica e precisa estar disponível 24 horas por dia, 7 dias por semana. O espelhamento da plataforma de dados IRIS da InterSystems fornece failover automático rápido, confiável e robusto com base na replicação lógica de dados. Caso o pior aconteca e um grande evento derrube um aplicativo ou serviço da nossa plataforma, o espelhamento oferece uma rápida recuperação de desastres.

Mais ferramentas e funcionalidades InterSystems IRIS interessantes que seram úteis para a plataforma:

InterSystems IRIS Adaptive Analytics:

  • O InterSystems IRIS Adaptive Analytics é uma extensão opcional que fornece uma camada de modelo de dados virtual orientada para os negócios entre o InterSystems IRIS e as populares ferramentas de cliente Business Intelligence (BI) e Artificial Intelligence (AI). O BI pode ser usado para criar painéis de controle e relatórios personalizados.

InterSystems DeepSee:

  • Esta ferramenta pode ser usada para criar visualizações de dados interativas e em tempo real, permitindo que os usuários do sistema explorem os dados de forma mais aprofundada e tomem decisões mais informadas.

InterSystems HealthShare:

  • O HealthShare, que é muito mais do que uma funcionalidade, pode ser usado para integrar dados de saúde dos alunos, permitindo que os médicos e os professores monitorem o bem-estar físico e mental dos alunos e ajudem a identificar e tratar problemas de saúde. Isso aqui só se o Brasil der mais um passo para o futuro utilizando InterSystems na saúde também, mas mesmo que não, sabemos que continua sendo possível graças a capacidade de integração com outros sistemas do InterSystems IRIS.

System Alerting and Monitoring:

  • System Alerting and Monitoring ( SAM ) é um componente independente que a InterSystems fornece para monitorar os produtos da InterSystems. Com este, mesmo que nossa plataforma seja executada em um par espelhado local ou na nuvem com vários aplicativos e servidores de dados, poderemos usar o SAM para monitorar as instâncias InterSystems IRIS. Usando o aplicativo da web SAM para visualizar métricas de desempenho em tempo real para clusters e instâncias.

InterSystems Reports

  • Como estamos lidando aqui com uma área de grande importância para a sociedade, com papel direto do governo precisamos de uma uma solução de relatórios moderna e robusta para garantir eficiência e segurança da plataforma e dar todo respaldo burocratico necessário. Que torna se possível graças ao InterSystems Reports, que é uma ferramenta de geração de relatórios para a plataforma de tecnologia InterSystems IRIS. Com o InterSystems Reports, é possível criar relatórios com gráficos, tabelas, imagens e outros elementos personalizados, além de definir layouts específicos para diferentes tipos de relatórios. A ferramenta também oferece suporte para relatórios em vários formatos, incluindo PDF, HTML, Excel e CSV, entre outros.

InterSystems IRIS® Natural Language Processing (NLP)

  • Análise de Texto (Processamento de Linguagem Natural), com esta tecnologia o InterSystems IRIS permite que se execute análise de texto em fontes de dados não estruturadas em uma variedade de linguagens naturais sem qualquer conhecimento prévio de seu conteúdo. Algo muito útil para as instituições de ensino que muitas vezes podem precisar de informações sobre o conteúdo de textos diversos, isso permite que se descubra informações úteis sobre o conteúdo de um grande número de documentos de texto sem nenhum conhecimento prévio do conteúdo dos textos.

A ferramenta InterSystems IRIS SQL Search

  • Esta ferramenta integra-se com o InterSystems IRIS Natural Language Processor (NLP) para executar operações de pesquisa de texto com reconhecimento de contexto em dados não estruturados, com recursos como pesquisa difusa, expressões regulares, lematização e decomposição. Esse recurso é fundamental para acessar o conteúdo de grandes volumes de texto armazenados em SQL.

PMML (Predictive Modeling Markup Language)

  • Como nossa plataforma servirá várias instituições de ensino que precisam trabalhar com análise e ciência de dados de forma otimizada, precisamos de um padrão que possibilite que modelos de mineração de dados e estatísticos possam ser compartilhados entre as aplicações de diferentes fornecedores. A maneira de fazer isso é usando PMML, que é suportado pela plataforma de dados InterSystems IRIS.

AutoML

  • Nossa! Cada vez mais imprecionado com o InterSystems IRIS, agora temos aqui mais uma funcionalidade super legal que será muito útil para uma plataforma como está, intimamente ligada ao machine learning. O AutoML é um sistema automatizado de aprendizado de máquina desenvolvido pela InterSystems, alojado na plataforma de dados InterSystems IRIS. Ele foi projetado para criar rapidamente modelos preditivos precisos, automatizando vários componentes-chave do processo de aprendizado de máquina. Depois de treinar o modelo com o AutoML, vamos poder implantá-lo facilmente usando a sintaxe SQL fornecida pelo IntegratedML. Isso é muito útil, imagine quanto tempo vamos economizar, vamos poder treinar diversos modelos relacionados a educação como: Modelo preditivo de desempenho acadêmico, Modelo preditivo de retenção de alunos, Modelo preditivo de engajamento, Modelo preditivo de recomendação de conteúdo, Modelo preditivo de detecção de plágio, Modelo preditivo de detecção de uso de IA na geração de textos e etc. tudo de forma automatizada. Para poder oferecer diversas ferramentas incríveis para transformar a educação totalmente.

Agora que vimos muitas funcionalidades do InterSystems IRIS que serão essenciais para este caso, vamos tentar vislumbrar como esta ideia pode transformar a educação:

Precisamo integrar em uma única plataforma toda a educação do país, escolas (públicas e privadas), faculdades (públicas e privadas), enfim todas as Instituições Credenciadas no MEC - Ministério da Educação, a ideia é que esta plataforma seja cedida pelo MEC, assim cada instituição teria sua própria instância.

Será preciso configurar as instâncias do IRIS para se comunicarem por meio de APIs e trocarem informações relevantes, como informações do aluno ou do professor.

A autenticação pode ser implementada para permitir que os usuários finais visualizem apenas os dados aos quais têm acesso, dependendo de seus perfis e funções (InterSystems API Manager). Por exemplo, um professor só poderia acessar os dados dos alunos que estão em suas turmas, enquanto um diretor poderia ter acesso a todos os dados dos alunos em sua escola.

Assim configurando de forma adequada as instâncias do InterSystems IRIS podemos fazer com que elas se comuniquem e troquem informações para fornecer uma visão unificada e completa do sistema educacional, permitindo que os usuários finais acessem facilmente as informações de que precisam, independentemente de sua localização física.

Vejamos:

Vamos integrar as instituições de todo o país para oferecer ferramentas de análise, educação, supervisão e outras. Teremos dados de alunos e instituições como por exemplo notas, perfil, ocorrências escolares, faltas, dados de IoT e etc; para por meio de Inteligência Artificial oferecer análises de desempenho e de pontos a melhorar, entre outras.

Será dividido entre interfaces especificas:

  • Pais - Teriam acesso à informações referentes aos seus filhos.
  • Professores - Teriam acesso à informações de todos seus alunos, podendo adicionar dados como notas.
  • Alunos - Poderiam acompanhar seu desempenho, receber dicas, tarefas e etc.
  • Diretores - Teriam uma grande ferramenta de Acompanhamente e análise.
  • Orgãos Responsáveis - Teriam uma visão geral da educação no país.

Com isso podemos dar a sociedade, uma ferramenta completa de educação, para acompanhar, receber dicas, análises, para oferecer materias de apoio com base no desempenho particular de cada um, podendo dar atenção específica para cada pessoa.

Também será algo gameficado, com pontuação, prêmios para os melhores desempenhos, incentivando o aprendizado e o bom comportamento, onde as pontuações e os dados de cada individuo seriam importantes para toda a vida profissional, sendo usado como complemento de notas obtidas em provas de admissão de faculdades e para seletivas de oportunidades de emprego.

Aqui temos um adendo:

  • Podemos integrar também dados das empresas, referente à vagas de emprego, permitindo que as empresas tenha acesso a uma interface de seleção de candidatos, com varios filtros, IA para seleção dos candidatos que mais se encaixam no perfil procurado.

  • E do lado dos alunos, estes poderiam fazer buscas por oportunidades, receber propostas de emprego e estágios, receber uma análise indicando onde ele precisa melhorar para aumentar suas chances na vaga que ele almeja.

Sabemos que emprego é o que não falta, o que falta é mão de obra qualificada, assim com esta plataforma, que só é possível graças ao InterSystems IRIS, podemos integradar os dados valiosos para tomada de decisão tanto de empresas na hora de escolher um candidato, como de instituições de ensino na hora de selecionar o que será ensinado em sala de aula e também claro do cidadão na hora de traçar seus objetivos para seu futuro profissional.

Assim temos em mãos a oportunidade de mudar tudo, inclusive o entusiasmo das crianças na hora de estudar, pois está será uma plataforma cheia de gamificação, sabemos que o mundo de hoje oferece muitas distrações para as crianças, por isso precisamos urgentemente atrair as crianças para um ambiente saudável, educativo e ao mesmo tempo divertido. Por isso nossa plataforma terá também a gamificação na sua forma máxima, com emblemas, pontuações, jogos educativos, prêmios e etc. Daremos valor ao bom comportamento, as boas notas, ao trabalho em equipe, tudo que um ser humano precisa para viver bem em uma sociedade saudável pode e deve ser desenvolvido nas escolas e é preciso mostrar para as crianças que isso tem valor, e não tem jeito melhor que com gameficação.

Outra coisa importante são os pais, que muitas vezes negligenciam ou delegam a educação dos seus filhos, com esta plataforma mudamos isso, trazendo os pais para mais perto da escola, dos professores e da educação dos seus filhos, com dicas, análises, comunicação e claro gameficação. Que tal também dar prêmios aos pais pelo desempenho de seus filhos? que tal descontos em supermercados? equipamentos tecnológicos?

Como estamos falando aqui de uma plataforma ligada diretamente aos governos municipais, estaduais e federal, esta parte de prêmios poderia vir integrada ao Cadastro Único para Programas Sociais (CadÚnico), no caso do Brasil, que é um instrumento de coleta de dados e informações que objetiva identificar todas as famílias de baixa renda existentes no país para fins de inclusão em programas de assistência social e redistribuição de renda. Integrar esses dados à plataforma para que os governos valorizem pais dedicados à educaçãos de seus filhos e alunos com ótimo desempenho.

Desafios

Sabendo que o caso de negócio escolhido aqui foi no setor da educação e que este caso foi escolhido pois é um setor de extrema importância para sociedade, listo abaixo os desafios encontrados:

  1. O primeiro desafio que podemos perceber em um projeto como este, está no fato de termos diferentes tipos de instituições de ensino no país, públicas, privadas e sem fins lucrátivos. E elas precisam estar, ao mesmo tempo, integradas e independentes. Por isso o InterSystems IRIS é tão importante, pois permite configurar as várias instâncias de forma que o usuário final terá uma visão unificada da plataforma, mesmo que cada instituição tenha sua própria instância InterSystems IRIS. Assim poderemos ter uma instância central ligada ao MEC que além de ter dados que são de responsábilidade do MEC, poderá consumir APIs das outras instâncias para obter os dados necessários e fornecer uma camada adicional de segurança e gerenciamento de acesso para as diferentes instâncias. Desta forma o front-end se comunica com a instância central, que é responsável por receber as solicitações do usuário final, processá-las e buscar as informações necessárias nas instâncias independentes e em si mesma em alguns casos. A instância central então retorna a resposta ao front-end, que apresenta as informações ao usuário final de forma unificada e amigável. Assim nosso modelo de comunicação terá uma "arquitetura centralizada".

  2. O segundo desafio se trata do fato de que hoje nas instituições provavelmente existem sistemas de diferentes fornecedores e com diferentes estruturas de dados que precisam ser integrados na plataforma, o que pode levar a muitos desafios relacionados a identificação de sistemas que precisam ser atualizados ou substituídos. O que é algo que pode ser resolvido de forma objetiva se levarmos em conta que o modelo educacional que temos hoje está obsoleto e precisamos substituir, se não todos, grande parte desses sistemas, para integrar tudo na nova plataforma, além claro do fato desta nova plataforma ser construido em cima do InterSystems IRIS que nos oferece uma interoperabilidade sem igual. Desafios aparecem, mas o InterSystems IRIS tem a solução.

  3. O terceiro é a questão da segurança, nossa plataforma precisa ser altamente segura para garantir que as informações pessoais de alunos, professores e outros estejam protegidas, além de garantir que apenas usuários autorizados tenham acesso a informações confidenciais. O que é algo que mais uma vez é facilitado pelo InterSystems IRIS. Mais abaixo vamos falar um pouco mais sobre isso.

Segurança, APIs e Modelo de Comunicação

Precisamos que nossa plataforma seja muito segura, saiba lidar com diferentes instâncias e que ao mesmo tempo, na percepção do usuário final, seja unificada.

Sabemos até aqui que está plataforma terá uma instância central que ficará sobre responsabilidade do MEC, e várias instâncias independentes e padronizadas sobre responsabilidade das instituições, desta forma vamos exemplificar abaixo como isso vai funcionar:

image

Para isso será preciso definir uma estrutura padronizada de APIs ao implementar as instâncias das instituições, para que a integração com a instância central seja realizada de maneira eficiente.

Assim ao cadastrar uma nova instituição na plataforma, será necessário incluir as informações referentes à API dessa instituição no banco de dados da instância central, permitindo que a comunicação entre as instâncias seja realizada de maneira adequada.

Outra coisa, é importante criar uma lógica de busca das informações de endpoint no banco de dados central, para que as informações sejam atualizadas automaticamente e o usuário final tenha acesso às informações da instituição correta.

Para implementar essa solução, será necessário utilizar o InterSystems API Manager e o ObjectScript para realizar a comunicação e integração entre as instâncias e o banco de dados central, a ideia é que o cadastro do usuário seja realizado na instância central, que poderá se comunicar também com outros serviços do governo para validar o cadastro, hoje no Brasil isso pode ser feito usando o gov.br que oferece um ambiente de autenticação digital único do usuário aos serviços públicos digitais, ou seja, com um único usuário e senha você poderá utilizar todos os serviços públicos digitais que estejam integrados com a plataforma GOV.BR. Fornece um nível de segurança compatível com o grau de exigência, natureza e criticidade dos dados e das informações pertinentes ao serviço público solicitado, assim, uma vez cadastrado, o usuário poderá ter acesso a todas as instituições do país diretamente na plataforma, podendo acessar seus dados de instituições onde está matriculado.

Desta forma quando uma pessoa realizar a matrícula em uma determinada instituição, um novo cadastro é gerado na instância local dessa instituição que vai validar os dados do aluno na instância central que por sua vez vai salvar a nova instituição nos dados do aluno para autenticação posterior.

Com esta lógica, precisamos que as instâncias das instituições disponibilizem as suas APIs e forneçam as credenciais de acesso para a instância central, teremos assim APIs especifícas e outras que possam vir a ser implementadas pelas instituições, também precisamos que cada instância das instituições de ensino forneça um serviço de autenticação integrado à plataforma central. Isso poderia ser feito usando um protocolo padrão, como OAuth 2.0, que permitiria que a instância central se autenticasse na instituição de ensino em nome do usuário, que poderá ser um diretor, um professor, aluno ou pai/mãe, funcionários e outros.

image

Uma vez autenticado, o sistema iria verificar em quais instituições o usuário tem acesso e mostrar apenas as informações relevantes para ele. Isso será implementado em ObjectScript usando uma combinação de APIs RESTful e lógica de negócios personalizada.

Supondo que um usuário faça login na plataforma central e seja autenticado com sucesso em uma instituição de ensino. A plataforma poderia então consultar um serviço RESTful na instituição para obter uma lista de cursos nos quais o usuário está matriculado. Essa solução garante que os usuários tenha acesso somente às informações relevantes para eles.

Com base nessa lista, a plataforma poderia exibir apenas os cursos relevantes para o usuário e ocultando todas as informações de outras instituições de ensino. O mesmo princípio poderia ser aplicado a outras informações, como notas, horários de aulas, calendários etc.

Observação: Como cada instituição terá sua própria instância InterSystems IRIS de forma independente isso abre possibilidade para que as instituições implementem novas APIs e desenvolvam outros aplicativos, além dos padronizados, que seriam disponibilizados na plataforma como numa loja de APPs. Como podemos ver o InterSystems IRIS abre um leque de oportunidades, onde podemos usar diversas abordagens tecnológicas para transformar a educação do país.

Agora o Machine Learning

Nossa plataforma é construida em cima do InterSystems IRIS, como já sabemos, e a principal abordagem tecnológica usada em conjunto é o Machine Learning, por isso veremos a seguir como o Machine Learning muda tudo aqui e nos dar uma capacidade incrível de transformação da educação.

Para esta parte vamos precisar do IntegrateML e do autoML, dois recursos imprecionantes presentes no InterSystems IRIS, com eles vamos poder treinar e implantar modelos preditivos facilmente. Vamos agora verificar tipos de modelos que poderemos treinar que serão de estrema importância para dar a esta plataforma o poder de transformar a educação:

  1. Modelo preditivo de desempenho acadêmico: Usando o autoML para criar rapidamente modelos preditivos precisos usando dados, como por exemplo notas de teste, vamos poder criar um modelo para prever o desempenho dos alunos em testes futuros. Ele pode ser usado para identificar os alunos que estão em risco de falhar em uma determinada disciplina e fornecer intervenções personalizadas para ajudá-los a melhorar.

  2. Modelo preditivo de retenção de alunos: Usando dados históricos de desempenho acadêmico, frequência, participação e outros, vamos poder criar um modelo para prever a probabilidade de um aluno abandonar a escola ou faculdade. Ele pode ser usado para identificar os alunos que correm maior risco de desistir e fornecer intervenções personalizadas para ajudá-los.

  3. Modelo preditivo de recomendação de conteúdo: Se lembra do que foi falado sobre atenção indívidual para acada aluno? Então, aqui podemos ter um modelo preditivo para a plataforma poder recomendar conteúdo específico com base nas preferências e desempenho acadêmico do aluno. Ele pode ser usado para oferecer conteúdo personalizado para cada aluno com base em suas necessidades individuais.

  4. Modelo preditivo de detecção de plágio: Algo muito importante para uma platforma como esta, que abre portas para se aumentar ainda mais o uso de computadores na realização de muitas tarefas, como entrega de trabalhos, provas e testes. Com Este modelo vamos poder detectar a ocorrência de plágio em trabalhos escritos de alunos. Ele pode ser usado para identificar trabalhos que possam ter sido plagiados evitando assim que os alunos copiem conteúdo da internet.

  5. Modelo preditivo de detecção de texto gerado por IA: Já que falamos de plágio, no ano de 2023 surgiu mais uma questão, o uso de IA para gerar texto para trabalhos acadêmicos, desta forma este modelo poderia identificar se um texto foi produzido por um ser humano ou por uma inteligência artificial. Isso seria útil em várias situações, como detecção de plágio, verificação de autenticidade de documentos, entre outros.

  6. Modelo preditivo de desempenho em testes padronizados: No Brasil temos ums prova chamada ENEM, que é muito importante na vida profissional, pois abre portas para a entrada em universidades públicas e privadas. Aqui podemos criar um modelo para prever o desempenho dos alunos em provas como o ENEM, imagine esta plataforma cheia de dados, como notas, análises grámaticas de textos feitos pelos alunos, dados de testes práticos gerados pela plataforma, provas anteriores do ENEM e outros. Com o autoML usamos esses dados para criar um modelo preditivo que será capaz de prever o desempenho do aluno no ENEM e identificar os alunos que precisam de mais suporte para melhorar seu desempenho. Imagina só, provas como estas estariam integradas a plataforma também, para que as pessoas recebam seus resultados direto na plataforma, juntamente com uma análise de desempenho e de pontos a melhorar, até porque a ideia é que toda a vida acadêmica da pessoa seja usada como parâmetro para ingressar numa faculdade ou receber uma oportunidade de emprego.

  7. Modelo preditivo de planejamento de carreira: Por falar em oportunidade de emprego, que tal um modelo que ajude no planejamento de carreira? Podemos usar dados de desempenho acadêmico e interesses pessoais para prever as carreiras mais adequadas para os alunos. Ele pode ser usado para oferecer sugestões personalizadas de carreira para os alunos e ajudá-los a planejar sua trajetória acadêmica e profissional.

  8. Modelo preditivo de personalização de ensino: Para um modelo como este poderemos utilizar dados de desempenho acadêmico, interesses e habilidades dos alunos para personalizar o conteúdo de ensino e atividades para cada aluno individualmente. Assim esta plataforma poderá criar experiências de aprendizado mais eficazes e personalizadas para os alunos, melhorando assim seu desempenho e engajamento.

  9. Modelo preditivo de avaliação de professores: Não podemos esquecer dos professores. Aqui temos um modelo que usa feedback dos alunos, dados de testes gerados pela plataforma para professores e etc, para avaliar a eficácia dos professores e identificar áreas de melhoria. Ele pode ser usado para fornecer informações úteis para os professores e administradores da escola e melhorar a qualidade do ensino.

  10. Modelo preditivo de análise de dados de engajamento dos pais: Já falamos aqui sobre pais que delegam a educação de seus filhos, então, com este modelo, que pode utilizar dados de engajamento dos pais, como comparecimento a reuniões escolares e comunicação com professores e até de pequenos testes gerados pela plataforma para verificar o conhecimento que os pais tem sobre os filhos, como por exemplo: qual foi a nota de joãozinho na prova de matemática da semana passada? para prever o envolvimento dos pais na educação de seus filhos. Ele pode ser usado para identificar áreas de oportunidade para aumentar o engajamento dos pais e melhorar a qualidade da educação.

  11. Modelo preditivo de análise de dados de IoT para segurança dos alunos: Aqui temos algo de extrema importância, um modelo que utiliza dados de dispositivos de segurança IoT, como câmeras e detectores de movimento, para prever possíveis ameaças à segurança dos alunos e prevenir incidentes. Por exemplo, o sistema pode detectar um comportamento suspeito em um indivíduo não identificado ou reconhecer padrões de tráfego para alertar a equipe de segurança sobre possíveis pontos de vulnerabilidade.

  12. Modelo preditivo de monitoramento de indicadores educacionais: Bom, neste caso teriamos um modelo preditivo construido com base em dados de diversas fontes, como avaliações de desempenho, taxas de abandono escolar e outros, para monitorar os indicadores educacionais em diferentes áreas e níveis educacionais. Com base nessas previsões o MEC e as instituições poderiam tomar decisões informadas sobre políticas e investimentos educacionais.

Bom existem milhares de modelos que podemos criar e implantar para esta plataforma usando AutoML e IntegrateML, com os modelos apresentados aqui podemos ver que esta plataforma tem a capacidade de transformar totalmente a educação de paises inteiros. Podemos também ter outros modelos relacionados à gestão e acompanhamento, para servir ferramentas para diretores, professores e orgãos responsáveis que iram auxiliá los na tomada de decisão.

Conclusão

Enfim, assim solucionamos este caso de negócio, tão grande e importante para a sociedade, pudemos ver aqui que com o uso de InterSystems IRIS aliado principalmente ao Machine Learning podemos solucionar milhares de problemas no setor educacional, dando a capacidade de se servir soluções inovadoras que podem transformar completamente a educação do Brasil.

A plataforma de educação integrada, a educação de um jeito que você nunca viu. A educação transforma e uma plataforma como esta é capaz de transformar países interios, pois tem o poder de levar a educação a um nível nunca visto antes.

image

6
2 326
Artigo Heloisa Paiva · Maio 26, 2023 6m read

Introdução

Dentre as diversas soluções que desenvolvemos aqui na Innovatium,  um desafio comum é a necessidade de acesso ao tamanho das bases de dados. Entretanto, notei que isso não é algo tão trivial no IRIS. Esse tipo de informação é importante para manter um controle do fluxo de dados e do custo em GB's de um sistema a ser implementado. Contudo, o que realmente me chamou atenção é a necessidade dela para uma função muito importante: migrar para cloud. Afinal, quem não quer migrar seus sistemas para cloud hoje em dia, certo?

0
0 141
Artigo Heloisa Paiva · Mar. 2, 2023 3m read

 Introdução

Esse é um tutorial simples da forma mais rápida que eu achei para criar uma base de dados de exemplo para quaisquer razões, como realizar testes, fazer exemplos para tutoriais, etc.

Criando um namespace

  1. Abra o terminal
  2. Escreva o comando "D $SYSTEM.SQL.Shell()"
  3. Escreva"CREATE DATABASE " e o nome desejado para o namespace.

Agora você tem um namespace novo de uma forma muito mais rápida que criando pelo Portal de Administração - que é claro que oferece muito mais opções de configuração.

0
0 146
Anúncio Cristiano Silva · Dez. 14, 2022

Fala pessoal!!!

Finalmente consegui um tempinho para organizar um conjunto de classes que venho utilizando alguns anos para facilitar e acabar com o trabalho repetitivo no desenvolvimento de intragrações utilizando XDBC.

Acessem o repositório do projeto no https://github.com/cristianojs/interopway

A idéia é incrementar o projeto com mais componentes, já tenho um que a massa está crescendo e jajá vai para o forno.

Quaisquer dúvidas postem aqui.

Grande abraço.

0
0 137
Artigo Danusa Calixto · Out. 18, 2022 17m read

Olá a todos, sou um estudante francês que acabou de chegar em Praga para um intercâmbio acadêmico no meu quinto ano da faculdade de engenharia e aqui está minha participação no concurso de interoperabilidade.

Não tive muito tempo para programar desde a mudança da França para Praga e estou participando sozinho, então decidi criar um projeto que é mais um modelo do que um aplicativo.

Queria participar já que minha área (Ciência de Dados e IA) não é geralmente associada à sustentabilidade, e o concurso era uma maneira de me expressar nesse tema importante que é a sustentabilidade e o meio ambiente.

Como você sabe, a Inteligência Artificial está cada vez mais popular, com várias firmas conhecidas tentando seguir o movimento e vender ferramentas para criar, treinar e usar modelos de machine learning com facilidade. Tudo isso é prático e fácil, mas tem um custo, financeiro e também ambiental.

Treinar modelos enormes repetidamente pode exigir muitos recursos e produzir uma grande quantidade de CO2. Os supercomputadores são executados durante vários dias, e o período e o tamanho dos modelos estão aumentando exponencialmente, tomando mais espaço do que nunca. Todo esse esforço para ter alguma melhoria no desempenho, que em alguns casos não é nem garantida.

É claro que várias firmas precisam desse processo, em que até mesmo 0,1% de melhoria na precisão de um modelo pode salvar milhares de vidas. Por isso, esse modelo foi criado para usos mais comuns.

No entanto, como tive a oportunidade de trabalhar com Processamento de Linguagem Natural (PLN) ou Classificação de Imagens, percebi que alguns modelos e ferramentas já são quase utilizáveis no estado em que se encontram e podem nos ajudar a economizar centenas de horas de treinamento e, consequentemente, emissões de CO2 e consumo de eletricidade.

Por isso, decidi criar um modelo usando as tecnologias da InterSystems para desenvolver uma solução interoperável que resolvesse alguns problemas de sustentabilidade ao permitir facilmente que você, em alguns cliques, faça o download único de modelos pré-treinados da Internet, use de acordo com sua própria necessidade e, claro, ajuste esses modelos pré-treinados com novo conteúdo disponível na base de dados IRIS e adicione conteúdo ao modelo existente.

Dessa forma, no modelo, estamos pegando um modelo PLN, testando e treinando com dados para criar cinco novos rótulos no modelo para classificar a avaliação da internet.

Portanto, ao fazer isso, o resultado (se você tiver tempo e algum poder computacional) é um ótimo modelo que pode ser usado para prever a nota de avaliação da internet, que não tem custo e emite uma quantidade pequena de CO2.

Consulte o GitHub e a postagem do Open Exchange vinculada a este artigo.

Ou veja o ReadMe aqui:

1. Contest-Sustainability

Este modelo usa as tecnologias da InterSystems para desenvolver uma solução interoperável e resolver alguns problemas de sustentabilidade ao permitir facilmente que você, em alguns cliques, faça o download único de modelos pré-treinados da Internet, use de acordo com sua própria necessidade e, claro, ajuste esses modelos pré-treinados com novo conteúdo disponível na base de dados IRIS e adicione conteúdo ao modelo existente.

Neste exemplo, estamos pegando um modelo PLN, testando e treinando com dados para criar cinco novos rótulos no modelo para classificar a avaliação da internet. No processo, poupamos uma grande quantidade de recursos e emissões de CO2.

Veja alguns modelos de exemplo que você pode testar: https://huggingface.co/gpt2
https://huggingface.co/Jean-Baptiste/camembert-ner
https://huggingface.co/bert-base-uncased
https://huggingface.co/facebook/detr-resnet-50
https://huggingface.co/facebook/detr-resnet-50-panoptic

ÍNDICE:

2. Instalação

2.1. Início da produção

Na pasta "contest-sustainability", abra um terminal e insira:

docker-compose up

Na primeira vez, talvez leve alguns minutos para o build correto da imagem e a instalação de todos os módulos necessários para o Python.

2.2. Acesso à produção

Seguindo este link, acesse a produção: Acessar a produção

2.3. Encerramento da produção

docker-compose down

3. Como funciona

Por enquanto, alguns modelos talvez não funcionem com essa implementação, já que tudo é feito automaticamente, ou seja, não importa o modelo de entrada, tentaremos fazer com que funcione usando a biblioteca transformerspipeline.

Pipeline é uma ferramenta poderosa da equipe HuggingFace que analisa a pasta em que o modelo foi transferido e entende qual biblioteca deve usar entre PyTorch, Keras, Tensorflow ou JAX. Em seguida, ela carrega esse modelo usando AutoModel.
Então, ao inserir a tarefa, o pipeline sabe o que fazer com o modelo, tokenizer ou até extrator de características nessa pasta e gerencia a entrada automaticamente, tokeniza, processa, transfere para o modelo e retorna um resultado decodificado que podemos usar diretamente.

4. API HuggingFace

Algumas pessoas ou sistemas não conseguem fazer o download de modelos ou usá-los devido a restrições. Por isso, é possível usar a API HuggingFace e chamar alguns modelos diretamente através desse serviço.
Veja uma explicação mais simples:

Primeiro, você precisa iniciar a demonstração, usando o botão verde Start, ou use Stop e Start novamente para aplicar as mudanças nas configurações.

Em seguida, ao clicar na operação Python.HFOperation escolhida e selecionar na guia à direita action, você pode aplicar test à demonstração.

Na janela test, selecione:

Tipo de solicitação: Grongier.PEX.Message

Em classname, insira:

msg.HFRequest

Para json, veja um exemplo de uma chamada para GPT2:

{
    "api_url":"https://api-inference.huggingface.co/models/gpt2",
    "payload":"Can you please let us know more details about your ",
    "api_key":"----------------------"
}

Agora, você pode clicar em Visual Trace para ver nos detalhes o que aconteceu e visualizar os registros.

OBSERVE que você precisa ter uma chave de API do HuggingFace antes de usar esta Operação (as chaves de API são gratuitas, basta fazer a inscrição no HF)

OBSERVE que você pode mudar o URL para testar outros modelos do HuggingFace. Talvez seja necessário mudar o payload.

Veja este exemplo:
envio de hf reqhf reqhf resp

5. Use qualquer modelo da Web

Nesta seção, vamos ensinar você a usar praticamente qualquer modelo pré-treinado da internet, HuggingFace ou não, para poupar recursos ou simplesmente usar esses modelos dentro do IRIS.

5.1. PRIMEIRO EXEMPLO: VOCÊ TEM SEU PRÓPRIO MODELO

Nesse caso, você precisa copiar e colar seu modelo, com config, tokenizer.json etc. dentro de uma pasta na pasta do modelo.
Caminho: src/model/yourmodelname/

Em seguida, você precisa criar uma nova operação, chame-a como quiser e acesse os parâmetros dessa operação.
Então, acesse settings na guia à direita, na parte Python e na parte %settings. Aqui, você pode inserir ou modificar quaisquer parâmetros (não se esqueça de pressionar apply depois de terminar).
Veja a configuração padrão para esse caso:
%settings

name=yourmodelname
task=text-generation

OBSERVE que qualquer configuração que não for name ou model_url entrará nas configurações PIPELINE.

Agora você pode clicar duas vezes na operação e executar o start. Você precisa ver na parte Log a inicialização do modelo.

Em seguida, criamos um PIPELINE utilizando transformers que usam o arquivo config na pasta como vimos antes.

Para chamar esse pipeline, clique na operação e selecione na guia à direita action. Você pode aplicar test à demonstração.

Na janela test, selecione:

Tipo de solicitação: Grongier.PEX.Message

Em classname, insira:

msg.MLRequest

Para json, você precisa inserir todos os argumentos necessários para o modelo.
Veja um exemplo de uma chamada para GPT2:

{
    "text_inputs":"Unfortunately, the outcome",
    "max_length":100,
    "num_return_sequences":3
}

Clique em Invoke Testing Service e aguarde a operação do modelo.

Veja este exemplo:
envio de ml req

Agora, você pode clicar em Visual Trace para ver nos detalhes o que aconteceu e visualizar os registros.

Veja este exemplo :
ml req

ml resp

5.2. SEGUNDO EXEMPLO: VOCÊ QUER FAZER O DOWNLOAD DE UM MODELO DO HUGGINGFACE

Nesse caso, você precisa encontrar o URL do modelo no HuggingFace.
Encontre um modelo que faça o que você busca e use-o sem gastar recursos utilizando as tecnologias da InterSystems.

5.2.1. Configurações

Vá até os parâmetros do Hugging.
Clique na operação HuggingFace escolhida e acesse settings na guia à direita, na parte Python e na parte %settings. Aqui, você pode inserir ou modificar quaisquer parâmetros (não se esqueça de pressionar apply depois de terminar).
Veja um exemplo de configuração para alguns modelos que encontramos no HuggingFace:

%settings para gpt2

model_url=https://huggingface.co/gpt2
name=gpt2
task=text-generation

%settings para camembert-ner

name=camembert-ner
model_url=https://huggingface.co/Jean-Baptiste/camembert-ner
task=ner
aggregation_strategy=simple

%settings para bert-base-uncased

name=bert-base-uncased
model_url=https://huggingface.co/bert-base-uncased
task=fill-mask

%settings para detr-resnet-50

name=detr-resnet-50
model_url=https://huggingface.co/facebook/detr-resnet-50
task=object-detection

%settings para detr-resnet-50-protnic

name=detr-resnet-50-panoptic
model_url=https://huggingface.co/facebook/detr-resnet-50-panoptic
task=image-segmentation

OBSERVE que qualquer configuração que não for name ou model_url entrará nas configurações PIPELINE. Então, no segundo exemplo, o pipeline camembert-ner requer a especificação de aggregation_strategy e task, enquanto gpt2 requer apenas uma task.

Veja este exemplo:
configurações ml ope2

Agora você pode clicar duas vezes na operação e executar o start.
Você precisa ver na parte Log a inicialização e o download do modelo.
OBSERVAÇÃO: Você pode atualizar os registros a cada x segundos para ver o avanço dos downloads. dl em tempo real

Em seguida, criamos um PIPELINE utilizando transformers que usam o arquivo config na pasta como vimos antes.

5.2.2. Teste

Para chamar esse pipeline, clique na operação e selecione na guia à direita action. Você pode aplicar test à demonstração.

Na janela test, selecione:

Tipo de solicitação: Grongier.PEX.Message

Em classname, insira:

msg.MLRequest

Para json, você precisa inserir todos os argumentos necessários para o modelo.
Veja um exemplo de uma chamada para GPT2:

{
    "text_inputs":"George Washington lived",
    "max_length":30,
    "num_return_sequences":3
}

Aqui está um exemplo de uma chamada para Camembert-ner:

{
    "inputs":"George Washington lived in washington"
}

Aqui está um exemplo de uma chamada para bert-base-uncased:

{
    "inputs":"George Washington lived in [MASK]."
}

Aqui está um exemplo de uma chamada para detr-resnet-50 usando um URL online:

{
    "url":"http://images.cocodataset.org/val2017/000000039769.jpg"
}

Aqui está um exemplo de uma chamada para detr-resnet-50-panoptic usando um URL como caminho:

{
    "url":"/irisdev/app/misc/000000039769.jpg"
}

Clique em Invoke Testing Service e aguarde a operação do modelo.
Agora, você pode clicar em Visual Trace para ver nos detalhes o que aconteceu e visualizar os registros.

OBSERVE que, após fazer pela primeira vez o download de um modelo, a produção não fará o download novamente, mas usará os arquivos em cache encontrados em src/model/TheModelName/.
Se alguns arquivos estiverem ausentes, a Produção fará o download novamente.

Veja este exemplo:
envio de ml reqml reqml resp

Veja este exemplo:
envio de ml reqml resp

6. Ajuste dos modelos

Nesta parte, tentamos ajustar um modelo para reaproveitá-lo e torná-lo ainda melhor sem usar muitos recursos.

6.1. Personalização do modelo

6.1.1. Download do modelo

Para utilizar esse GitHub, você precisa ter um modelo do HuggingFace compatível com pipeline para usar e treinar, além de um conjunto de dados para treinar seu modelo.

Para ajudar, oferecemos a possibilidade de usar script Python em src/utils/download_bert.py. Ele fará o download para você do modelo "https://huggingface.co/bert-base-cased" e colocará dentro da pasta src/model/bert-base-cased se já não estiver lá.
Além disso, também disponibilizamos um conjunto de dados para treinar o modelo bert. Esse conjunto de dados já estava carregado dentro da base de dados IRIS e nenhuma ação adicional é necessária se você quiser usá-lo. (Para acessá-lo, vá até a parte SQL do portal, o namespace da base de dados iris e depois a tabela de revisão)

Para usar o script, se você estiver no contêiner, pode executá-lo sem se preocupar. Se você estiver no local, talvez seja necessário aplicar pip3 install requests e pip3 install beautifulsoup4

Veja o resultado: Download do resultado

6.1.2. Configurações

Se você quiser usar o modelo bert-base-cased e já fez o download usando o script, não é necessário adicionar mais nada às configurações, e você pode avançar para o treinamento do modelo.

Se você quiser treinar seu próprio modelo, clique em Python.TuningOperation e selecione Settings na guia à direita, depois Python e, na parte %settings, insira o caminho do modelo, o nome da pasta e o número do rótulo que você quer para o treinamento.

Exemplo:

path=/irisdev/app/src/model/
model_name=bert-base-cased
num_labels=5

6.1.3. Treinamento do modelo

Para treinar o modelo, você precisa acessar Production neste link:

http://localhost:52795/csp/irisapp/EnsPortal.ProductionConfig.zen?PRODUCTION=iris.Production

E conectar usando:
SuperUser como nome de usuário e SYS como senha.


Para chamar o treinamento, clique em Python.TuningOperation e selecione na guia à direita Actions. Você pode aplicar Test à demonstração.

Na janela de teste, selecione:

Tipo de solicitação: Grongier.PEX.Message

Em classname, insira:

msg.TrainRequest

Para json, você precisa inserir todos os argumentos necessários para o treinamento. Aqui está um exemplo que treina com as primeiras 20 linhas (não é um treinamento adequado, mas é rápido):

{
    "columns":"ReviewLabel,ReviewText",
    "table":"iris.Review",
    "limit":20,
    "p_of_train":0.8,

    "output_dir":"/irisdev/app/src/model/checkpoints",
    "evaluation_strategy":"steps",
    "learning_rate":0.01,
    "num_train_epochs":1
}

Veja este exemplo: Pedido de treinamento

Como pode ver, é preciso inserir

  • a table usada.
  • as columns usadas (primeiro é label e segundo é input para a tokenização)
  • o limit de linhas compreendidas (se você não especificar um número de linhas, todos os dados serão usados)
  • p_of_train, a porcentagem de dados de treinamento usados do conjunto de dados, e 1 - p_of_train, a porcentagem de dados de teste usados do conjunto de dados.

Depois disso, os outros parâmetros cabem a você e podem variar de acordo com os parâmetros https://huggingface.co/docs/transformers/main_classes/trainer.

OBSERVE que o tamanho do lote para treinamento e teste será calculado automaticamente se não for inserido na solicitação. (É o maior divisor do número de linhas que é menor do que a raiz quadrada do número de linhas e do que 32)

Clique em "Invoke Testing Service" e feche a janela de teste sem esperar.
Agora acesse Python.TuningOperation e selecione na guia à direita log. Aqui você pode ver o avanço do treinamento e das avaliações.
Após a conclusão, você verá um log dizendo que o novo modelo foi salvo em uma pasta temporária.
Agora acesse Python.TuningOperation, selecione na guia à direita message e clique no cabeçalho do último item para selecioná-lo. Aqui você pode ver o avanço do treinamento e das avaliações e, ao final, é possível acessar as Métricas do modelo novo e antigo para comparação.

6.1.4. Substituição do modelo

Se você quiser manter o modelo antigo, nenhuma ação é necessária: o antigo permanecerá na pasta não temporária e ainda será carregado para treinamento adicional.

Se você quiser manter o modelo novo, clique em Python.TuningOperation, selecione na guia à direita Actions e teste. Na janela de teste, selecione:

Tipo de solicitação: Grongier.PEX.Message

Em classname, insira:

msg.OverrideRequest

Para json, chaves vazias:

{}

Clique em Invoke Testing Service e veja a mensagem de resposta. O novo modelo foi movido da pasta temporária para a não temporária.

6.2. Uso do modelo

Treinar um modelo é interessante, mas você também pode testá-lo.

6.2.1. Configurações

Se você quiser usar o modelo bert-base-cased e já fez o download usando o script, não é necessário adicionar mais nada às configurações, e você pode avançar para o teste do modelo.

Se você quiser treinar seu próprio modelo, clique em Python.TuningOperation e selecione Settings na guia à direita, depois Python e, na parte %settings, insira o parâmetro para adicionar ao pipeline.

6.2.2. Teste do modelo

Para testar o modelo, você precisa acessar Production neste link:

http://localhost:52795/csp/irisapp/EnsPortal.ProductionConfig.zen?PRODUCTION=iris.Production

E conectar usando:
SuperUser como nome de usuário e SYS como senha.


Para chamar o teste, clique em Python.MLOperation e selecione na guia à direita Actions. Você pode aplicar Test à demonstração.

Na janela de teste, selecione:

Tipo de solicitação: Grongier.PEX.Message

Em classname, insira:

msg.MLRequest

Para json, você precisa inserir todos os argumentos necessários para o modelo funcionar

{
    "inputs":"This was a really bad experience"
}

Pressione Call test services e veja o resultado.

7. Observação importante

O ajuste fino de modelos pode exigir MUITO tempo e recursos, mas sempre consumirá menos recursos do que o treinamento de um modelo do zero.
Você pode ver que já está levando muito tempo e poder computacional para o ajuste fino do modelo, então imagine o custo se tivesse que treiná-lo do zero e começar de novo várias vezes para obter resultados ideais.

8. Solução de problemas

Se você tiver problemas, a leitura é o primeiro conselho que podemos dar a você. A maioria dos erros são facilmente compreendidos apenas ao ler os logs, pois quase todos os erros são capturados por um try/catch e registrados.

Se você precisar instalar um novo módulo ou dependência do Python, abra um terminal dentro do contêiner e digite, por exemplo: "pip install new-module"
Há várias formas de abrir um terminal,

  • Se você usa os plugins da InterSystems, pode clicar na barra abaixo no VSCode, que se parece com docker:iris:52795[IRISAPP], e selecionar Open Shell in Docker.
  • Em qualquer terminal local, digite: docker-compose exec -it iris bash
  • No Docker-Desktop, encontre o contêiner IRIS e clique em Open in terminal

Alguns modelos talvez exijam algumas alterações no pipeline ou nas configurações, por exemplo. É sua responsabilidade adicionar as informações corretas nas configurações e na solicitação.

9. Conclusão

Daqui em diante, você poderá usar modelos de que talvez precise no IRIS e ajustá-los como desejar.
Esse modelo precisa ser modificado para atender às suas necessidades e foi criado como base para qualquer projeto de IA e IRIS que considere a sustentabilidade e interoperabilidade.

Por falta de tempo, não consegui adicionar uma API que usasse um Diretor para se comunicar diretamente com a produção e permitir que os usuários fizessem solicitações aos modelos.
No entanto, se você ainda tiver interesse em uma API IRIS usando esse módulo do Python, confira meu GitHub ou acesse meu exemplo de API no Python para IRIS.

Link para meu perfil do DC: https://community.intersystems.com/user/lucas-enard-0

0
0 71
Anúncio Rochael Ribeiro · Mar. 23, 2022

Olá Desenvolvedores!

Aqui estão os bonus tecnológicos para o Concurso de Globais InterSystems 2022 que irão lhes dar pontos extra na votação:

  • Implementação de Modelo de Dados - 5
  • Implementação de índice Funcional - 5
  • Uso do Data Move - 3
  • Python Nativo- 4
  • Uso de APIs de Globais  - 2
  • Uso de contêiner Docker - 2 
  • Implantação em pacote ZPM - 2
  • Demonstração Online - 2
  • Primeiro Artigo na Comunidade de Desenvolvedores - 2
  • Segundo Artigo na Comunidade de Desenvolvedores - 1
  • Validação da Qualidade de Código - 1
  • Vídeo no YouTube - 3

Vejam os detalhes abaixo.<--break-><--break->

0
0 80
Artigo Fernando Ferreira · Mar. 18, 2022 8m read

Olá comunidade! Nesta parte do artigo temos um cenário onde o nosso ambiente InterSystems Caché/Ensemble possui um ou mais servidores com Shadow e/ou Mirror.

Como comentado no início do artigo, componentes de um software possuem uma evolução natural e outros componentes são deprecados. E uma tecnologia muito utilizada pelos nossos clientes que está deprecada no InterSystems IRIS é o Shadow (esta informação está na página 18 do documento InterSystems IRIS Adoption Guide que volto a recomendar que você faça o download no WRC).

0
1 319
Artigo Fernando Ferreira · Mar. 3, 2022 5m read

Continuação:
Migrando para InterSystems IRIS – Parte 02 – Trocando de sistema operacional e de hardware.

Olá, comunidade! Nesta continuação da segunda parte do artigo vamos apresentar dicas do processo de migração do InterSystems Caché e ou Ensemble para IRIS com um desafio um pouco maior, pois agora vamos trocar de máquina e sistema operacional.

Como comentado na 1ª parte do artigo, a ideia é passar dicas e não substituir os documentos oficiais que estão disponíveis no WRC, que são eles:

  • InterSystems IRIS Adoption Guide;
  • How to migrate to InterSystems IRIS.

Cenário atual:

0
0 276
Artigo Gerson Saito · Fev. 21, 2022 6m read

A plataforma de dados InterSystems IRIS © agora apresenta suporte nativo completo para Python, liberando o poder da linguagem de programação mais popular do mundo para criar aplicativos de missão crítica com uso intensivo de dados.

https://www.intersystems.com/news-events/news/news-item/embedded-python-intersystems-iris-data-platform/

Essa decisão estratégica leva em consideração vários fatores:

  • A grande escala no uso de Python dentro das corporações
  • Python passou ser a um padrão de fato para desenvolvimento de modelos de Machine Learning (ML)
  • A grande oferta e demanda de programadores Python.

A seguir iremos explorar esses pontos.

0
0 194
Artigo Fernando Ferreira · Fev. 3, 2022 5m read

Migrando para InterSystems IRIS – Parte 02 (Instância única de Caché/Ensemble para IRIS)

Olá, comunidade, nessa segunda parte do artigo vou dar dicas do processo de migração de uma instância única de InterSystems Caché e ou Ensemble para IRIS.

Como comentado na 1ª parte do artigo, a ideia é passar dicas e não substituir os documentos oficiais que estão disponíveis no WRC, que são eles:

  • InterSystems IRIS Adoption Guide;
  • How to migrate to InterSystems IRIS.

Vamos então agora colocar a mão na massa!

O sistema operacional que estou usando como exemplo, é uma instalação em um ambiente Ubuntu:

0
1 412