Skip to main content

Controlling Database Objects from Python

The Native SDK works together with InterSystems External Servers, allowing your external Python application to control instances of database classes written in either ObjectScript or Embedded Python. Native SDK inverse proxy objects can use External Server connections to create a target database object, call the target’s instance methods, and get or set property values as easily as if the target were a native Python object.

This section covers the following topics:

Introducing the Python External Server

The Python External Server allows InterSystems IRIS embedded language objects and Python Native SDK objects to interact freely, using the same connection and working together in the same context (database, session, and transaction). External Server architecture is described in detail in Using InterSystems External Servers, but for the purposes of this discussion you can think of it as a simple black box connecting proxy objects on one side to target objects on the other:

Python External Server System
External Server gateway connecting an ObjectScript application in InterSystems IRIS with a Python application

As the diagram shows, a forward proxy is a database object that controls an external Python target object. The corresponding Native SDK object is an inverse proxy that controls a database target object from an external Python application, inverting the normal flow of control.

Creating Python Inverse Proxy Objects

You can create an inverse proxy object by obtaining the OREF of a database class instance (for example, by calling the %New() method of an ObjectScript class). The IRIS.classMethodObject() and IRIS.functionObject() methods will return an IRISObject instance if the call obtains a valid OREF. The following example uses IRIS.classMethodObject() to create an inverse proxy object:

Creating an instance of IRISObject
      proxy = irispy.classMethodObject("User.TestInverse","%New");
  • classMethodObject() calls the %New() method of an ObjectScript class named User.TestInverse

  • The call to %New() creates a database instance of User.TestInverse.

  • classMethodObject() returns inverse proxy object proxy, which is an instance of IRISObject mapped to the database instance.

This example assumes that irispy is a connected instance of IRIS (see “Creating a Connection in Python”). See “Calling Database Methods and Functions from Python” for more information on how to call class methods.

The following section demonstrates how proxy can be used to access methods and properties of the ObjectScript User.TestInverse instance.

Controlling Database Objects with IRISObject

The iris.IRISObject class provides several methods to control the database target object: invoke() and invokeVoid() call an instance method with or without a return value, and accessors get() and set() get and set a property value. .

This example uses an ObjectScript class named User.TestInverse, which includes declarations for methods initialize() and add(), and property name:

ObjectScript sample class TestInverse
Class User.TestInverse Extends %Persistent {
  Method initialize(initialVal As %String = "no name") {
    set = initialVal
  Method add(val1 As %Integer, val2 As %Integer) As %Integer {
   return val1 + val2
  Property name As %String;

The first line of the following example creates a new instance of User.TestInverse and returns inverse proxy object proxy, which is mapped to the database instance. The rest of the code uses proxy to access the target instance. Assume that a connected instance of IRIS named irispy already exists (see “Creating a Connection in Python”).

Using inverse proxy object methods in Python
  # Create an instance of User.TestInverse and return an inverse proxy object for it
  proxy = irispy.classMethodObject("User.TestInverse","%New");

  # instance method proxy.initialize() is called with one argument, returning nothing.
  proxy.invokeVoid("initialize", "George");
  print("Current name is "+ proxy.get("name"));   # display the initialized property value

  # instance method proxy.add() is called with two arguments, returning an int value.
  print("Sum of 2 plus 3 is " + str(proxy.invoke("add",2,3))); 

  # The value of property is displayed, changed, and displayed again.
  proxy.set("name", "Einstein, Albert");  # sets the property to "Einstein, Albert"
  print("New name is "+ proxy.get("name"));   # display the new property value

This example uses the following methods to access methods and properties of the User.TestInverse instance:

  • IRISObject.invokeVoid() invokes the initialize() instance method, which initializes a property but does not return a value.

  • IRISObject.invoke() invokes instance method add(), which accepts two integer arguments and returns the sum as an integer.

  • IRISObject.set() sets the name property to a new value.

  • IRISObject.get() returns the value of property name.

This example used the variant get(), and invoke() methods, but the IRISObject class also provides datatype-specific Typecast Methods for supported datatypes:

IRISObject get() typecast methods

In addition to the variant get() method, IRISObject provides the following IRISObject.get() typecast methods: getBytes(), getDecimal() getFloat() getInteger(), getString(), getIRISList(), and getObject().

IRISObject invoke() typecast methods

In addition to invoke() and invokeVoid(), IRISObject provides the following IRISObject.invoke() typecast methods: invokeBytes(), invokeDecimal(), invokeInteger(), invokeString(), invokeIRISList(), and invokeObject().

All of the invoke() methods take a str argument for methodName plus 0 or more method arguments. The arguments may be either Python objects, or values of supported datatypes. Database proxies will be generated for arguments that are not supported types.

invoke() can only call instance methods of an IRISObject instance. See “Calling Database Methods and Functions from Python” for information on how to call class methods.