Nova postagem

Pesquisar

Anúncio
· jan 23

Developing with InterSystems Objects and SQL – Virtual February 10-14, 2025 / Registration space available

Developing with InterSystems Objects and SQL – Virtual February 10-14, 2025

  • This 5-day course teaches programmers how to use the tools and techniques within the InterSystems® development environment.
  • Students develop a database application using object-oriented design, building different types of IRIS classes.
    • They learn how to store and retrieve data using Objects or SQL, and decide which approach is best for different use cases.
    • They write code using ObjectScript, Python, and SQL, with most exercises offering the choice between ObjectScript and Python, and some exercises requiring a specific language.
  • This course is applicable for users of InterSystems IRIS® data platform and InterSystems Caché®
  • Self-Register Here
Discussão (0)1
Entre ou crie uma conta para continuar
Anúncio
· jan 23

Top InterSystems Ideas Contributors of 2024

Hi Community!

It's time to share the Ideas Portal 2024 annual stats and the Top InterSystems Ideas Contributors of 2024 🌟

General Stats:

✓ 135 new ideas posted in 2024
✓  47 implemented ideas:
          ✓   24 ideas implemented by Community members
          ✓   23 ideas implemented by InterSystems
✓ 289 new comments posted
✓ 274 new users registered 

Implementer of Ideas:
 
Nomination: Implementer of ideas
Badge's name Badge's logo Winners
Implementer of Ideas    

@Yuri Marx Pereira Gomes

@Rob Ellis

Congratulations to the developers who earned this badge in 2024 👏🏅

Most Voted Ideas:
   
Most Commented Ideas:
   
Idea Leaders:
 
Developer Number of posted ideas
@Scott Roth 11
@Veerarajan Karunanithi 7
@Luis Angel Pérez Ramos  6
 
Idea Commenters:
 
Developer Number of comments
@Benjamin De Boe 20
@Robert Cemper 7
@Raj Singh 6
@Dmitry Maslennikov 6
 

Congratulations! Thank you all for your contributions to the InterSystems Ideas Portal in 2024!

We look forward to seeing more of your inspiring ideas in 2025! 💡✨

7 Comments
Discussão (7)3
Entre ou crie uma conta para continuar
Artigo
· jan 23 7min de leitura

Python Embutido no InterSystems IRIS

Olá comunidade,

Neste artigo, vou descrever e ilustrar o processo de implementação do ObjectScript dentro do Python embutido. Esta discussão também fará referência a outros artigos relacionados ao Python embutido, bem como abordará questões que foram benéficas para a minha jornada de aprendizado.

Como você sabe, a integração de recursos Python dentro do IRIS tem sido possível há algum tempo. Este artigo se concentrará em como incorporar perfeitamente o ObjectScript com o Python embutido.

Essencialmente, o Python embutido serve como uma extensão que permite a escrita e execução independentes. Ele permite a integração perfeita do código Python com o ObjectScript e vice-versa, permitindo que ambos sejam executados dentro do mesmo contexto. Essa funcionalidade aprimora significativamente as capacidades da sua implementação.

Para começar, você deve especificar a linguagem para o seu código Python dentro da definição da classe usando a palavra-chave "language" [language = "python"]. Feito isso, você está preparado para escrever o seu código Python.

import iris - O pacote iris é uma biblioteca Python vital que facilita a comunicação com as classes nativas, rotinas, globais e SQL do InterSystems. Este pacote está prontamente disponível por padrão. De qualquer forma, é necessário importar este pacote no início do seu código Python se você for interagir com o IRIS.

Algumas notas importantes antes de escrever

  • Você pode usar a variável especial do Python __name__ para se referir ao nome da classe dentro da definição da classe.
  • Use _ para %Methods ex: %New  == _New , %OpenId == _OpenId

Vamos começar

Implementação de membros de classe em Python Embutid

1.  Objetos e Propriedades

Esta seção é essencial, pois abordará o processo de inicialização de um novo objeto, alteração dos valores de objetos existentes e configuração de propriedades em contextos estáticos e dinâmicos. Crie sua própria definição de classe e use as propriedades literais simples

1.1 Inicializar novo Objeto / Modificar objeto existente

Use _New para iniciar um novo objeto e _OpenId(id) para editar o objeto existente

ClassMethod SaveIRISClsObject() [ Language = python ]
{
 #this method calls the %OnNew callback method and get the object
 import iris
 try:
     iris_obj =  iris.cls(__name__)._New()
     if not iris.cls(__name__).IsObj(iris_obj):
      #IsObj is the objectscript wrapper method : which contains $Isobject()
         raise ReferenceError('Object Initlize Error')
 except ReferenceError as e:
     print(e)
     return
 #set the object properties and save the values
 iris_obj.Name = 'Ashok'
 iris_obj.Phone = 9639639635
 status = iris_obj._Save()
 print(status)
 return status
}

1.2 Accessando propriedades

Antes de iniciar a seção sobre propriedades, é importante observar que o tipo de dados IRIS difere dos tipos de dados Python, e portanto, os tipos de dados de coleção IRIS não podem ser utilizados diretamente dentro do Python. Para solucionar isso, a InterSystems ofereceu uma solução abrangente para converter tipos de dados IRIS em formatos compatíveis com Python, como listas, conjuntos e tuplas. Isso pode ser alcançado importando o módulo "builtins" dentro da base de código IRIS, utilizando os métodos de classe ##class(%SYS.Python).Builtins() ou definindo builtins = ##class(%SYS.Python).Import("builtins").
Abordarei isso nas próximas seções. 

Então, eu uso esse métood para converter as propriedades $LB em lista  python para acessar as propriedades em tempo de execução no python.

LEARNING>Set pyList = ##class(%SYS.Python).ToList($LB("Name","Phone","City"))
 
LEARNING>zw pyList
pyList=5@%SYS.Python  ; ['Name', 'Phone', 'City']  ; <OREF>
ClassMethod GetProperties() [Language = objectscript]
{
    set pyList = ##class(%SYS.Python).ToList($LB("Name","Phone","City"))
    do ..pyGetPropertiesAtRunTime(pyList)
}
ClassMethod pyGetPropertiesAtRunTime(properties) [ Language = python ]
{
    import iris
    iris_obj = iris.cls(__name__)._OpenId(1)
    for prop in properties:
        print(getattr(iris_obj,prop))
}

 

1.3 Defina propriedades em tempo de execução

Utilizo este dicionário Python para designar minha propriedade como chave e, com os valores de propriedade correspondentes servindo como valores dentro desse dicionário. Você pode consultar o código fornecido abaixo e a postagem da comunidade relacionada a essa configuração de propriedade.

ClassMethod SetProperties()
{
	Set pyDict = ##class(%SYS.Python).Builtins().dict()
	do pyDict.setdefault("Name1", "Ashok kumar")
	do pyDict.setdefault("Phone", "9639639635")
	do pyDict.setdefault("City", "Zanesville")
	Set st = ..pySetPropertiesAtRunTime(pyDict)
}

ClassMethod pySetPropertiesAtRunTime(properties As %SYS.Python) [ Language = python ]
{
	import iris
	iris_obj = iris.cls(__name__)._New()
	for prop in properties:
		setattr(iris_obj, prop,properties[prop])
	
	status = iris_obj._Save()
	return status
}

1.4 Contexto de objetos compartilhados

Como mencionado anteriormente, tanto Python quanto ObjectScript operam dentro do mesmo contexto de memória e compartilham objetos. Isso significa que você pode criar ou abrir um objeto na classe InCache e posteriormente definir ou recuperá-lo na classe Python.

ClassMethod ClassObjectAccess() [Language = objectscript]
{
	Set obj = ..%OpenId(1)
	Write obj.PropAccess(),! ; prints "Ashok kumar"
	Do obj.DefineProperty("test")
	Write obj.PropAccess() ; prints "test"
}

Method PropAccess() [ Language = python ]
{
	
return self.Name
}

Method DefineProperty(name) [ Language = python ]
{
	
self.Name = name
}

2.  Parâmetros

Obtenha o par chave-valor arbitrário do parâmetro usando o método _GetParameter. Consulte o útil post da comunidade.

ClassMethod GetParam(parameter = "MYPARAM") [ Language = python ]
{
	import iris
	value = iris.cls(__name__)._GetParameter(parameter)
	print(value)
}

3. Class Method e Methods

3.1 Class Method

A invocação de métodos e funções de classe é altamente benéfica para a execução do código ObjectScript.

Invoque o método de classe como uma chamada estática, por exemplo: Do ..Test() 

ClassMethod InvokeStaticClassMethods(clsName = "MyLearn.EmbeddedPython") [ Language = python ]
{
	import iris
	print(iris.cls(clsName).Test())
	# print(iris.cls(__name__).Test()) 
}


Invoque o método de classe em tempo de execução Set method="Test" Do $ClassMethod(class, method, args...)

ClassMethod InvokeClassMethodsRunTime(classMethod As %String = "Test") [ Language = python ]
{
 import iris
 clsMethodRef = getattr(iris.cls(__name__), classMethod) # will return the reference of the method
 print(clsMethodRef()) 
}

3.2  Methods

A invocação dos métodos de instância é feita da mesma forma que no formato 'ObjectScript'. No código abaixo, primeiro inicializo o objeto e, em seguida, chamo o método de instância com parâmetros.

ClassMethod InvokeInstanceMethodWithActualParameters() [ Language = python ]
{
	import iris
	obj = iris.cls(__name__)._New()
	print(obj.TestMethod(1,2,4))
}

3.3  Passagem de argumentos por valor e por referência entre Python e ObjectScript

Basicamente, a passagem de argumentos é inevitável entre funções e seguirá o mesmo comportamento entre ObjectScript e Python.

3.4 Passagem por valor - É a passagem por valor usual.

ClassMethod passbyvalfromCOStoPY()
{
    Set name = "test", dob= "12/2/2002", city="chennai"
    Do ..pypassbyvalfromCOStoPY(name, dob, city)
}

ClassMethod pypassbyvalfromCOStoPY(name As %String, dob As %String, city As %String) [ Language = python ]
{
   print(name,'  ',dob,'  ',city)
}

/// pass by value from  python to object script
ClassMethod pypassbyvalfromPY2COS() [ Language = python ]
{
	import iris
	name = 'test'
	dob='12/2/2002'
	city='chennai'
	iris.cls(__name__).passbyvalfromPY2COS(name, dob, city)
}

ClassMethod passbyvalfromPY2COS(name As %String, dob As %String, city As %String)
{
    zwrite name,dob,city
}

3.5 Passagem por referência Diferentemente da passagem por valor. Como o Python não suporta nativamente a passagem por referência, é necessário utilizar o iris.ref() no código Python para tornar a variável uma referência. Consulte a referência. Pelo que sei, não há efeitos no lado ObjectScript em relação a variáveis passadas por referência, mesmo quando essas variáveis são modificadas em Python. Consequentemente, as variáveis Python serão afetadas por esse mecanismo de passagem por referência quando os métodos do ObjectScript forem invocados.

ClassMethod pypassbyReffromPY2COS() [ Language = python ]
{
	import iris
	name='python'
	dob=iris.ref('01/01/1991')
	city = iris.ref('chennai')
	print('before COS ',name,'  ',dob.value,'  ',city.value)
	#pass by reference of dob, city
	iris.cls('MyLearn.EmbeddedPythonUtils').passbyReffromPY2COS(name, dob, city)	
	print('after COS ',name,'  ',dob.value,'  ',city.value)
}

ClassMethod passbyReffromPY2COS(name, ByRef dob, ByRef city)
{
  Set name="object script", dob="12/12/2012", city="miami"
}

// output 
LEARNING>do ##class(MyLearn.EmbeddedPythonUtils).pypassbyReffromPY2COS()
before COS  python    01/01/1991    chennai
after COS  python    12/12/2012    miami
 


3.5 **kwargs- Existe suporte adicional para passar argumentos de palavra-chave Python (**kwargs)a partir do ObjectScript. Como o InterSystems IRIS não possui o conceito de argumentos de palavra-chave, é necessário criar um   %DynamicObject para armazenar os pares chave-valor e passar os valores usando a sintaxe Args...

Eu criei o dynamicObject "name""ashok""city""chennai"}e nele defini os pares chave-valor necessários, passando-o posteriormente ao código Python.

ClassMethod KWArgs()
{
    set kwargs={ "name": "ashok", "city": "chennai"}
    do ..pyKWArgs(kwargs...)
}

ClassMethod pyKWArgs(name, city, dob = "") [ Language = python ]
{
    print(name, city, dob)
}

// output
LEARNING>do ##class(MyLearn.EmbeddedPythonUtils).KWArgs()
ashok chennai

No próximo artigo, tratarei de assuntos como variáveis globais, rotinas e SQL.

Discussão (0)1
Entre ou crie uma conta para continuar
Pergunta
· jan 23

%REST.API swagger specs generation from comments / response type

Hi, I am currently setting up a new API using %CSP.REST - I've gotten swagger spec generation to work like such:

Class Api.DispatchRouter Extends %CSP.REST
{

XData UrlMap
{
<Routes>

<Map Prefix="/test" Forward="Api.Controllers.TestController"/>

<Route Url="/swagger" Method="GET" Call="SwaggerSpec"/>   
</Routes>
}

ClassMethod SwaggerSpec() As %Status
{
    Set tSC = ##class(%REST.API).GetWebRESTApplication($NAMESPACE, %request.Application, .swagger)
    Do swagger.info.%Remove("x-ISC_Namespace")
    Set swagger.basePath = "/csp/myapi"
    Set swagger.info.title = "My API"
    Set swagger.info.version = "0.0.0"
    Set swagger.host = "myhost.com"
    Return ..%WriteJSON($$$OK, swagger)
}

}
Class Api.Controllers.TestController Extends %CSP.REST
{

XData UrlMap
{
<Routes>

<Route Url="/:name" Method="GET" Call="Test"/>

</Routes>
}

/// This gets read by Swagger, can I add metadata here?
ClassMethod Test(name As %String) As %Status
{
    write "works!: " _ name, !
    Return $$$OK
}

}

 

This correctly reads all the endpoints inside the TestController based on the UrlMap, but it does not know the return type

I would like to be able to add additional info to each individual endpoint, for starters to manually define the possible return types/objects, as well as parameters from the %request, directly inside a comment above the ClassMethod.

 

I'd rather have it auto-generate the swaggerspec, so I'm wondering if anyone can point me in the right direction.

I have also heard of isc-rest package, but unless the features are outstanding, I'd prefer to stay away.

3 Comments
Discussão (3)1
Entre ou crie uma conta para continuar
Artigo
· jan 22 2min de leitura

第四章 C 开头的术语

 

# 第四章 C 开头的术语

#### 循环引用 (circular reference)

**对象(Objects)**

在不同类中的两个属性相互引用对方的集合。只要循环引用中的两个属性都不是必需属性,`IRIS` 完全支持循环引用。如果循环引用中的两个属性都是必需属性,你将无法保存这两个类的对象。

#### 类编译器 (class compiler)

**对象(Objects)**

类编译器用于编译`IRIS` 类。你可以在 `IDE` 中使用类编译器,或者通过 ` IRIS` 对象实用库中的编译调用来使用。

#### 类定义语言 (Class Definition Language)

**对象(Objects)**

`IRIS` 的类定义语言(`CDL`)是一种基于关键字的语言,用于定义 `IRIS` 中的类。

#### 类描述符 (class descriptor)

**对象(Objects)**

包含运行时信息(方法和属性列表)的特殊类型例程,用于使用对象。

#### 类字典 (class dictionary)

**对象(Objects)**

类字典保存所有已编译类的当前类定义。`SQL` 也使用类字典来确定有效的表定义。

#### 类层次结构 (class hierarchy)

**对象(Objects)**

类层次结构显示从每个根类到其每个子类及其子类的类链。

#### 类成员 (class member)

**对象(Objects)**

属于类的元素。类成员可以是属性、方法、参数、查询、索引、触发器或 `XData` 块。

#### 类方法 (class method)

**对象(Objects)**

无论其类的实例是否在内存中,都可以调用的方法。

#### 类 (class)

**对象(Objects)**

类封装了单一实体的状态和行为。一个类包括一些类型信息和一组类成员,包括属性、方法、参数、查询和索引。

`IRIS` 支持两种主要类型的类:数据类型类和对象类。它支持多种对象类,包括抽象类、抽象持久类、持久类、可嵌入类、非注册类、注册类和系统类。

#### 客户端数据类型 (client data type)

**对象(Objects)**

客户端数据类型用于指定通过`IRIS` 对象服务器向客户端投射数据所需的信息。每个数据类型类必须有一个客户端数据类型。基于数据类型类的属性将该类的客户端数据类型投射为属性的数据类型,以供 `SQL` 和 `Java` 等客户端使用。

#### 客户端锁 (client lock)

**系统**

请参见外发锁(outgoing lock)。

#### 客户端 (client)

**系统**

运行你应用程序的机器。它连接到数据库所在的服务器机器。也指网络上的一个节点,可以向其他节点请求信息。

Discussão (0)1
Entre ou crie uma conta para continuar