Home Applications iris-global-reference

iris-global-reference Awaiting Review

InterSystems does not provide technical support for this project. Please contact its developer for the technical assistance.
0
0 reviews
0
Awards
3
Views
0
IPM installs
0
0
Details
Releases (1)
Reviews
Issues
Pythonic global access

What's new in this version

Initial Release

1. IRIS Global Reference Python API

  • Magic in place of Basic
  • Some picture of globals (tree array)

A Pythonic wrapper around InterSystems IRIS globals providing an intuitive interface for working with hierarchical data.

2. Introduction

InterSystems IRIS is a powerful database platform that provides a unique hierarchical data structure called globals. Globals are a key-value store that can be used to store hierarchical data in a tree-like structure. This hierarchical data structure is very powerful but can be difficult to work with using traditional programming languages.

The IRIS Global Reference Python API is a Pythonic wrapper around InterSystems IRIS globals that provides an intuitive interface for working with hierarchical data. The API provides a set of core methods for working with globals, including data operations, node information, navigation, and iteration. The API also provides support for converting globals to dictionaries and JSON and back, making it easy to work with hierarchical data in Python.

Key differences with globals and dictionaries:

  • Globals don’t have a notion of arrays
    • This project provides a serialization to store arrays in globals
  • A global node can have both values and child nodes
    • In a dictionary, a node can have either a value or child nodes, but not both
      • To solve this, the API binds the root node to None key
  • Globals are ordered
    • Dictionaries are unordered

3. Installation

pip install iris-global-reference

to have direct access to an iris terminal, you can use the following command:

pip install iris-global-reference --target=/python

4. Basic Usage

Here’s a comprehensive example showing various ways to interact with globals:

from iris_global import GlobalReference

Create a reference to a global

team = GlobalReference("^demo") team.kill() # Clear any existing data

Different ways to set values

team.set((), "Baseball") # Set root node team["name"] = "Boston Red Sox" # Dictionary-style assignment team.set(("players", "1"), "Babe Ruth") # Tuple subscript team.set(["players", "2"], "Cy Young") # List subscript team["players", "3"] = "Ted Williams" # Multiple subscripts

Different ways to get values

print(team.get(())) # Get root value: "Baseball" print(team["name"]) # Dictionary-style access print(team.get(("players", "1"))) # Using get() method print(team["players"]["2"]) # Nested dictionary-style

Check if nodes exist

print(("players", "1") in team) # True print("nonexistent" in team) # False

Delete nodes

del team["players", "3"] # Delete using del team.kill(("players", "2")) # Delete using kill()

Iteration Examples

1. Iterate through all nodes and values

for key, value in team.items(): print(f"Node {key}: {value}") # Shows all nodes with values

Output :

Node (): Baseball

Node ('name',): Boston Red Sox

Node ('players', '1'): Babe Ruth

2. Iterate through direct children only

for key in team.keys(children_only=True): print(f"Direct child: {key}") # Shows only root level nodes

Output:

Direct child: ()

Direct child: ('name',)

3. Custom iteration with subscripts

for sub in team.subscripts(("players",), children_only=True): print(f"Player: {team.get(sub)}") # Shows only players

Output:

Player: Babe Ruth

Count direct children

print(len(team)) # Number of root level nodes

Output:

3

Display global structure

print(team.zw()) # Show ZWRITE format

Output:

^demo="Baseball"

^demo("name")="Boston Red Sox"

^demo("players","1")="Babe Ruth"

Display this global in a dictionary format

print(team.to_dict())

Output:

{

None: 'Baseball',

'name': 'Boston Red Sox',

'players': {

'1': 'Babe Ruth'

}

}

5. Support of remote connection

You can use the GlobalReference class with embedded Python by omitting the connection,
or connect to a remote IRIS instance by passing the native iris connection returned by
iris.connect(...).

import iris
from iris_global import GlobalReference

Embedded Python, running inside IRIS.

team = GlobalReference("^demo")

Remote connection, running outside IRIS.

conn = iris.connect("localhost", 1972, "USER", "SuperUser", "SYS") team = GlobalReference("^demo", connection=conn)

Set values

team.set((), "Baseball") team.set(("name",), "Boston Red Sox") team.set(("players", "1"), "Babe Ruth")

Get values

print(team.get(())) # Baseball print(team.get(("name",))) # Boston Red Sox print(team.get(("players", "1"))) # Babe Ruth

SQLAlchemy engines and iris://... connection strings are no longer supported by
GlobalReference. Use iris.connect(host, port, namespace, username, password) for
remote access.

6. Core Methods

6.1. Data Operations

  • set(subscript, value): Set a value at the specified node
  • get(subscript): Get the value at the specified node
  • kill(subscript): Delete a node and all its descendants
  • delete(subscript): Same as kill() but more Pythonic

6.1.1. set() Method

The set() method can be used to set values at any node in the global:

team.set((), "Baseball")

can be used to set the root node, while:

team.set(("name",), "Boston Red Sox")

sets a child node with subscript “name”.

set can also be used with str or list subscript:

team.set("", "Baseball")
team.set("name", "Boston Red Sox")
team.set(["players", "1"], "Babe Ruth")

You can also use dictionary type subscript:

team["name"] = "Boston Red Sox"
team["players", "1"] = "Babe Ruth"
team["players"]["1"] = "Babe Ruth"

6.1.2. get() Method

The get() method can be used to retrieve values at any node in the global:

team.get(())  # Returns "Baseball"
team.get(("name",))  # Returns "Boston Red Sox"
team.get(("players", "1"))  # Returns "Babe Ruth"

get can also be used with str or list subscript:

team.get("")  # Returns "Baseball"
team.get("name")  # Returns "Boston Red Sox"
team.get(["players", "1"])  # Returns "Babe Ruth"

You can also use dictionary type subscript:

print(team["name"])  # Returns "Boston Red Sox"
print(team["players", "1"])  # Returns "Babe Ruth"
print(team["players"]["1"])  # Returns "Babe Ruth"

6.1.3. kill() Method

The kill() method can be used to delete a node and all its descendants:

team.kill(("players",))

kill can also be used with str or list subscript:

team.kill("players")
team.kill(["players"])

You can also use dictionary type subscript:

del team["players"]

6.1.4. delete() Method

Same as kill() but more Pythonic.

6.2. Node Information

  • data(subscript): Get node status (0=undefined, 1=value only, 10=descendants only, 11=both)
  • has_value(subscript): Check if node has a value
  • has_descendants(subscript): Check if node has child nodes

6.2.1. data() Method

The data() method can be used to get the status of a node:

from iris_global import GlobalReference

data = { None: "root", "a": {1: "value a"} }

team = GlobalReference("^data").from_dict(data)

print(team.data(())) # 11 (node with descendants and value) print(team.data(("a",))) # 10 (node with descendants only) print(team.data(("a", 1))) # 1 (node with value only) print(team.data(("b",))) # 0 (undefined node)

Works with str or list subscript:

print(team.data(""))  # 11
print(team.data("a"))  # 10
print(team.data(["a", 1]))  # 1
print(team.data("b"))  # 0

6.2.2. has_value() Method

The has_value() method can be used to check if a node has a value:

from iris_global import GlobalReference

data = { None: "root", "a": {1: "value a"} }

team = GlobalReference("^data").from_dict(data)

print(team.has_value(())) # True print(team.has_value(("a",))) # False print(team.has_value(("a", 1))) # True print(team.has_value(("b",))) # False

Works with str or list subscript:

print(team.has_value(""))  # True
print(team.has_value("a"))  # False
print(team.has_value(["a", 1]))  # True
print(team.has_value("b"))  # False

6.2.3. has_descendants() Method

The has_descendants() method can be used to check if a node has child nodes:

from iris_global import GlobalReference

data = { None: "root", "a": {1: "value a"} }

team = GlobalReference("^data").from_dict(data)

print(team.has_descendants(())) # True print(team.has_descendants(("a",))) # True print(team.has_descendants(("a", 1))) # False print(team.has_descendants(("b",))) # False

Works with str or list subscript:

print(team.has_descendants(""))  # True
print(team.has_descendants("a"))  # True
print(team.has_descendants(["a", 1]))  # False
print(team.has_descendants("b"))  # False

6.3. Navigation

  • next(subscript, direction): Get next subscript at same level (direction=1) or previous (direction=-1)
  • previous(subscript): Get previous subscript at the same level
  • query(subscript, direction): Navigate through nodes like ObjectScript $QUERY
  • order(subscript, direction): Legacy through nodes like ObjectScript $ORDER

6.3.1. next() Method

The next() method can be used to get the next subscript:

from iris_global import GlobalReference

Create a reference to a global

team = GlobalReference("^demo")

Set values

team.set((), "Baseball") team.set(("name",), "Boston Red Sox") team.set(("players", "1"), "Babe Ruth") team.set(("players", "2"), "Cy Young")

Query nodes

print(team.next(())) # Returns ("name",) print(team.next(("name",))) # Returns ("players",) print(team.next(("players",))) # Returns ("players", "1") print(team.next(("players", "1"))) # Returns ("players", "2") print(team.next(("players", "2"))) # Returns None

works with str or list subscript:

print(team.next(""))  # Returns ("name",)
print(team.next("name"))  # Returns ("players",)
print(team.next("players"))  # Returns ("players", "1")
print(team.next(["players", "1"]))  # Returns ("players", "2")
print(team.next(["players", "2"]))  # Returns None

6.3.2. query() Method

Same as next().

The query() method can be used to navigate through nodes like ObjectScript $QUERY:

from iris_global import GlobalReference

Create a reference to a global

team = GlobalReference("^demo")

Set values

team.set((), "Baseball") team.set(("name",), "Boston Red Sox") team.set(("players", "1"), "Babe Ruth") team.set(("players", "2"), "Cy Young")

Query nodes

print(team.query(())) # Returns ("name",) print(team.query(("name",))) # Returns ("players",) print(team.query(("players",))) # Returns ("players", "1") print(team.query(("players", "1"))) # Returns ("players", "2") print(team.query(("players", "2"))) # Returns None

works with str or list subscript:

print(team.query(""))  # Returns ("name",)
print(team.query("name"))  # Returns ("players",)
print(team.query("players"))  # Returns ("players", "1")
print(team.query(["players", "1"]))  # Returns ("players", "2")
print(team.query(["players", "2"]))  # Returns None

6.3.3. order() Method

Legacy method to navigate through nodes like ObjectScript $ORDER:

from iris_global import GlobalReference

Create a reference to a global

team = GlobalReference("^demo")

Set values

team.set((), "Baseball") team.set(("name",), "Boston Red Sox") team.set(("players", "1"), "Babe Ruth") team.set(("players", "2"), "Cy Young")

Get next subscript

print(team.order(())) # Returns "name" print(team.order(("name",))) # Returns "players" print(team.order(("players",))) # Returns None print(team.order(("players", ""))) # Returns "1" print(team.order(("players", "1"))) # Returns "2" print(team.order(("players", "2"))) # Returns None

works with str or list subscript:

print(team.order(""))  # Returns "name"
print(team.order("name"))  # Returns "players"
print(team.order("players"))  # Returns None
print(team.order(["players", ""]))  # Returns "1"
print(team.order(["players", "1"]))  # Returns "2"
print(team.order(["players", "2"]))  # Returns None

6.4. Iteration

Note: subscript value are always returned as string tuples

  • subscripts(subscript, direction, with_descendants, with_values, with_root, children_only): Get all subscripts at subscript level
  • keys(subscript, direction, with_descendants, with_values, with_root, children_only): Get all subscripts at subscript level
  • values(subscript, direction, with_descendants, with_values, with_root, children_only): Get all values at subscript level
  • items(subscript, direction, with_descendants, with_values, with_root, children_only): Get all subscripts and values at subscript level

6.4.1. subscripts() Method

The subscripts() method can be used to get all subscripts at a subscript level.

Signature:

  • subscripts(subscript, direction=1, with_descendants=False, with_values=False, with_root=False, children_only=False)
    • subscript: Subscript to start from
    • direction: Direction (1=forward, -1=backward)
    • with_descendants: Include child nodes default: False
    • with_values: Only include nodes with values default: False
    • with_root: Include the start node default: False
    • children_only: Only include direct children default: False

Note: subscripts aim to have the same behavior as ObjectScript $ORDER

from iris_global import GlobalReference

Create a reference to a global

team = GlobalReference("^demo")

Set values

team.set((), "Baseball") team.set(("name",), "Boston Red Sox") team.set(("players", "1"), "Babe Ruth") team.set(("players", "2"), "Cy Young") team.set(("world_series", "1"), "1903") team.set(("world_series", "2"), "1912")

Get all subscripts

for subscript in team.subscripts(): print(subscript) # Returns ('name',), ('players',), ('world_series',)

Get subscripts starting from "players"

for subscript in team.subscripts(("players",)): print(subscript) # Returns ('world_series',)

Get subscripts starting from "players" that are nested

for subscript in team.subscripts(("players","")): print(subscript) # Returns ('players', '1'), ('players', '2')

or

for subscript in team.subscripts(("players",), children_only=True): print(subscript) # Returns ('players', '1'), ('players', '2')

Get subscripts only with values

for subscript in team.subscripts(with_values=True): print(subscript) # Returns ('name',)

Get subscripts only with descendants

for subscript in team.subscripts(with_descendants=True): print(subscript) # Returns ('name',), ('players',), ('players', '1'), ('players', '2'), ('world_series',), ('world_series', '1'), ('world_series', '2')

Get subscripts with root node

for subscript in team.subscripts(with_root=True): print(subscript) # Returns (), ('name',), ('players',), ('world_series',)

Get subscripts only with descendants and values

for subscript in team.subscripts(with_descendants=True, with_values=True): print(subscript) # Returns ('name',), ('players', '1'), ('players', '2'), ('world_series', '1'), ('world_series', '2')

Get subscripts with root node and descendants and values

for subscript in team.subscripts(with_root=True, with_descendants=True, with_values=True): print(subscript) # Returns (), ('name',), ('players', '1'), ('players', '2'), ('world_series', '1'), ('world_series', '2')

6.4.2. keys() Method

The keys() method can be used to get all subscripts at a subscript level.

Signature:

  • keys(subscript, direction=1, with_descendants=True, with_values=True, with_root=True, children_only=False)
    • subscript: Subscript to start from
    • direction: Direction (1=forward, -1=backward)
    • with_descendants: Include child nodes default: True
    • with_values: Only include nodes with values default: True
    • with_root: Include the start node default: True
    • children_only: Only include direct children default: False

Note: keys aim to have the same behavior as Python dictionary keys()
It means return all subscripts with values by descending all branches including the root node
Basically, same as subscripts(with_descendants=True, with_values=True, with_root=True)
Aim to be close as possible to ObjectScript ZWRITE

from iris_global import GlobalReference

Create a reference to a global

team = GlobalReference("^demo")

Set values

team.set((), "Baseball") team.set(("name",), "Boston Red Sox") team.set(("players", "1"), "Babe Ruth") team.set(("players", "2"), "Cy Young") team.set(("world_series", "1"), "1903") team.set(("world_series", "2"), "1912")

Get keys

for key in team.keys(): print(key) # Returns (), ('name',), ('players', '1'), ('players', '2'), ('world_series', '1'), ('world_series', '2')

Get all keys

for key in team.keys(with_values=False): # Returns all subscripts even without values print(key) # Returns ('name',), ('players',), ('players', '1'), ('players', '2'), ('world_series',), ('world_series', '1'), ('world_series', '2')

Get keys starting from "players"

for key in team.keys(("players",)): print(key) # Returns ('players', '1'), ('players', '2'), ('world_series', '1'), ('world_series', '2')

Get keys starting from "players" that are nested

for key in team.keys(("players",), children_only=True): print(key) # Returns ('players', '1'), ('players', '2')

or

for key in team.keys(("players","")): print(key) # Returns ('players', '1'), ('players', '2')

6.4.3. values() Method

The values() method can be used to get all values at a subscript level.

Signature:

  • values(subscript, direction=1, with_descendants=True, with_values=True, with_root=True, children_only=False)
    • subscript: Subscript to start from
    • direction: Direction (1=forward, -1=backward)
    • with_descendants: Include child nodes default: True
    • with_values: Only include nodes with values default: True
    • with_root: Include the start node default: True
    • children_only: Only include direct children default: False

Note: values aim to have the same behavior as Python dictionary values()
It means return all values by descending all branches including the root node

from iris_global import GlobalReference

Create a reference to a global

team = GlobalReference("^demo")

Set values

team.set((), "Baseball") team.set(("name",), "Boston Red Sox") team.set(("players", "1"), "Babe Ruth") team.set(("players", "2"), "Cy Young") team.set(("world_series", "1"), "1903") team.set(("world_series", "2"), "1912")

Get values

for value in team.values(): print(value) # Returns "Baseball", "Boston Red Sox", "Babe Ruth", "Cy Young", "1903", "1912"

6.4.4. items() Method

The items() method can be used to get all subscripts and values at a subscript level.

Signature:

  • items(subscript, direction=1, with_descendants=True, with_values=True, with_root=True, children_only=False)
    • subscript: Subscript to start from
    • direction: Direction (1=forward, -1=backward)
    • with_descendants: Include child nodes default: True
    • with_values: Only include nodes with values default: True
    • with_root: Include the start node default: True
    • children_only: Only include direct children default: False

Note: items aim to have the same behavior as Python dictionary items()
It means return all subscripts and values by descending all branches including the root node

from iris_global import GlobalReference

Create a reference to a global

team = GlobalReference("^demo")

Set values

team.set((), "Baseball") team.set(("name",), "Boston Red Sox") team.set(("players", "1"), "Babe Ruth") team.set(("players", "2"), "Cy Young") team.set(("world_series", "1"), "1903") team.set(("world_series", "2"), "1912")

Get items

for key, value in team.items(): print(key, value) # Returns (), "Baseball", ('name',), "Boston Red Sox", ('players', '1'), "Babe Ruth", ('players', '2'), "Cy Young", ('world_series', '1'), "1903", ('world_series', '2'), "1912"

6.4.5. zw() Method

The zw() method can be used to display the global in ObjectScript ZWRITE format:

from iris_global import GlobalReference

Create a reference to a global

team = GlobalReference("^demo")

Set values

team.set((), "Baseball") team.set(("name",), "Boston Red Sox") team.set(("players", "1"), "Babe Ruth") team.set(("players", "2"), "Cy Young") team.set(("world_series", "1"), "1903") team.set(("world_series", "2"), "1912")

print(team.zw())

^demo=Baseball

^demo("name")="Boston Red Sox"

^demo("players","1")="Babe Ruth"

^demo("players","2")="Cy Young"

^demo("world_series","1")="1903"

^demo("world_series","2")="1912"

7. Dictionary & JSON Operations

Convert globals to dictionaries or JSON and back.

  • to_dict(subscript, with_descendants, with_values, with_root, children_only, merge_leafs): Export global to dictionary
  • from_dict(data): Import dictionary to global
  • to_json(subscript, with_descendants, with_values, with_root, children_only, merge_leafs): Export global to JSON
  • from_json(json_str, root_name): Import JSON to global

7.1. to_dict() Method

The to_dict() method can be used to export a global to a dictionary.

Signature:

  • to_dict(subscript=None, with_descendants=True, with_values=True, with_root=True, children_only=False, merge_leafs=True)
    • subscript: Subscript to start from
    • with_descendants: Include child nodes default: True
    • with_values: Only include nodes with values default: True
    • with_root: Include the start node default: True
    • children_only: Only include direct children default: False
    • merge_leafs: Merge leaf nodes into a single value default: True
from iris_global import GlobalReference

Create a reference to a global

team = GlobalReference("^demo")

Set values

team.set((), "Baseball") team.set(("name",), "Boston Red Sox") team.set(("players", "1"), "Babe Ruth") team.set(("players", "2"), "Cy Young") team.set(("world_series", "1"), "1903") team.set(("world_series", "2"), "1912")

Export to dictionary

data_dict = team.to_dict() print(data_dict)

returns:

{

None: "Baseball",

"name": "Boston Red Sox",

"players": {

"1": "Babe Ruth",

"2": "Cy Young"

},

"world_series": {

"1": "1903",

"2": "1912"

}

}

Note: root node is bound to None key

Note: leaf nodes are merged by default

Export to dictionary unmeged

print(team.to_dict(merge_leafs=False))

returns:

{

None: "Baseball",

"name": {None: "Boston Red Sox"},

"players": {

"1": {None: "Babe Ruth"},

"2": {None: "Cy Young"}

},

"world_series": {

"1": {None: "1903"},

"2": {None: "1912"}

}

}

7.2. from_dict() Method

The from_dict() method can be used to import a dictionary to a global.

from iris_global import GlobalReference

Create a reference to a global

team = GlobalReference("^demo")

Dictionary data

data_dict = { None: "Baseball", "name": "Boston Red Sox", "players": { "1": "Babe Ruth", "2": "Cy Young" }, "world_series": { "1": "1903", "2": "1912" } }

Note: root node is bound to None key

Import dictionary

team.from_dict(data_dict)

Unmerged dictionary data can be imported as well

data_dict = { None: "Baseball", "name": {None: "Boston Red Sox"}, "players": { "1": {None: "Babe Ruth"}, "2": {None: "Cy Young"} }, "world_series": { "1": {None: "1903"}, "2": {None: "1912"} } }

team_unmerged = GlobalReference("^unmerged") team_unmerged.from_dict(data_dict)

Check values

team_unmerged.to_dict() == team.to_dict() # True

7.3. to_json() Method

The to_json() method can be used to export a global to JSON.

Signature:

  • to_json(subscript=None, with_descendants=True, with_values=True, with_root=True, children_only=False, merge_leafs=True, root_name="_")
    • subscript: Subscript to start from
    • with_descendants: Include child nodes default: True
    • with_values: Only include nodes with values default: True
    • with_root: Include the start node default: True
    • children_only: Only include direct children default: False
    • merge_leafs: Merge leaf nodes into a single value default: True
    • root_name: Rename the root node
from iris_global import GlobalReference

Create a reference to a global

team = GlobalReference("^demo")

Set values

team.set((), "Baseball") team.set(("name",), "Boston Red Sox") team.set(("players", "1"), "Babe Ruth") team.set(("players", "2"), "Cy Young") team.set(("world_series", "1"), "1903") team.set(("world_series", "2"), "1912")

Export to JSON

print(team.to_json())

returns:

{

"name": "Boston Red Sox",

"players": {

"1": "Babe Ruth",

"2": "Cy Young"

},

"world_series": {

"1": "1903",

"2": "1912"

},

"_": "Baseball"

}

Note: root node is bound to "_"

Note: leaf nodes are merged by default

Export to JSON unmeged

print(team.to_json(merge_leafs=False))

returns:

{

"name": {"_": "Boston Red Sox"},

"players": {

"1": {"_": "Babe Ruth"},

"2": {"_": "Cy Young"}

},

"world_series": {

"1": {"_": "1903"},

"2": {"_": "1912"}

},

"_": "Baseball"

}

Root node can be renamed

print(team.to_json(root_name="root"))

returns:

{

"name": "Boston Red Sox",

"players": {

"1": "Babe Ruth",

"2": "Cy Young"

},

"world_series": {

"1": "1903",

"2": "1912"

},

"root": "Baseball"

}

7.4. from_json() Method

The from_json() method can be used to import JSON to a global.

import json
from iris_global import GlobalReference

Create a reference to a global

team = GlobalReference("^demo")

JSON data

json_str = """ { "name": "Boston Red Sox", "players": { "1": "Babe Ruth", "2": "Cy Young" }, "world_series": { "1": "1903", "2": "1912" }, "_": "Baseball" } """

Import JSON

team.from_json(json_str)

Check values

print(json.loads(json_str) == json.loads(team.to_json())) # True

Root node can be renamed

json_str = """ { "name": "Boston Red Sox", "players": { "1": "Babe Ruth", "2": "Cy Young" }, "world_series": { "1": "1903", "2": "1912" }, "root": "Baseball" } """

team.from_json(json_str, root_name="root")

Check values

print(json.loads(json_str) == json.loads(team.to_json(root_name="root"))) # True

8. Python Magic Methods

GlobalReference implements Python magic methods for a more Pythonic experience:

# Dictionary-like access
team["name"] = "Boston Red Sox"
print(team["name"])
del team["players", "3"]

Check if node exists

if ("players", "1") in team: print("Player exists!")

Get number of direct child nodes

num_nodes = len(team)

Iterate directly

for key,value in team: print(key, value)

Values returned with [] are Key objects. For string, integer, float, and bytes values,
the returned key is also a subclass of the matching Python primitive:

name = team["name"]
isinstance(name, str)  # True

Bracket access on a Key is always global child access, not native primitive indexing.
Use .value, str(key), or bytes(key) when you need primitive indexing:

team["name"][0]        # Looks up subscript ("name", 0)
team["name"].value[0]  # Returns first character from the string value

Boolean values are returned as plain Key wrappers because Python does not allow
subclassing bool.

9. Array support

Note: Array support is experimental

To support array from dict/json, i used a serialization to store the array in a global.
The serialization is the following:

  • the root node contains an serialization string eg: __array__
  • the children nodes contains the array values
  • the children nodes are named with the serialization string and the index of the array

example:

from iris_global import GlobalReference

GlobalReference("demo").kill()

gref = GlobalReference("demo")

my_dict = {"a": 1, "b": 2, "array": [1, 2, 3], "array_of_dicts": [{"a": 1}, {"b": 2}]} gref.from_dict(my_dict)

print(gref.to_dict()) # {'a': 1, 'array': [1, 2, 3], 'array_of_dicts': [{'a': 1}, {'b': 2}], 'b': 2} print(gref.zw())

^demo("a")=1

^demo("array")="array"

^demo("array","__array__0")=1

^demo("array","__array__1")=2

^demo("array","__array__2")=3

^demo("array_of_dicts")="array"

^demo("array_of_dicts","__array__0","a")=1

^demo("array_of_dicts","__array__1","b")=2

^demo("b")=2

can still present global as dict without serialization

print(gref.to_dict(merge_array=False))

returns:

{

'a': 1,

'array': {None: 'array', '__array__0': 1, '__array__1': 2, '__array__2': 3},

'array_of_dicts': {None: 'array', '__array__0': {'a': 1}, '__array__1': {'b': 2}},

'b': 2

}

the serialization string can be changed

gref.kill() gref.from_dict(my_dict, array_prefix="list") print(gref.zw())

^demo("a")=1

^demo("array")="list"

^demo("array","__list__0")=1

^demo("array","__list__1")=2

^demo("array","__list__2")=3

^demo("array_of_dicts")="list"

^demo("array_of_dicts","__list__0","a")=1

^demo("array_of_dicts","__list__1","b")=2

^demo("b")=2

10. Transaction support

Transactions can be supported by using the with statement:

from iris_global import GlobalReference

Create a reference to a global with a transaction

with GlobalReference("^demo") as team: team.set((), "Baseball") team.set(("name",), "Boston Red Sox") team.set(("players", "1"), "Babe Ruth") team.set(("players", "2"), "Cy Young")

or

from iris_global import GlobalReference

Create a reference to a global

team = GlobalReference("^demo")

Set values

team.set((), "Baseball")

Start transaction

with team: team.set(("name",), "Boston Red Sox") team.set(("players", "1"), "Babe Ruth") team.set(("players", "2"), "Cy Young")

Otherwize, you can use the begin(), commit() and rollback() methods:

from iris_global import GlobalReference

Create a reference to a global

team = GlobalReference("^demo")

Set values

team.set((), "Baseball")

Start transaction

team.begin() team.set(("name",), "Boston Red Sox")

Commit transaction

team.commit()

11. Benefits

  • Pythonic: Provides a Pythonic interface for working with globals
  • Intuitive: Simplifies working with hierarchical data
  • Efficient: Reduces the need for complex ObjectScript code
  • Flexible: Supports a wide range of data operations

11.1. Merge operation

ObjectScript has a merge operation that can be used to merge two globals. This operation is not supported by the API. However, you can achieve the same result by exporting the globals to dictionaries, merging the dictionaries, and then importing the merged dictionary back to a global.

from iris_global import GlobalReference

Create a reference to a global

team1 = GlobalReference("^team1") team11 = GlobalReference("^team11") team2 = GlobalReference("^team2")

Set values

team1.set((), "Baseball") team1.set(("name",), "Boston Red Sox") team1.set(("players", "1"), "Babe Ruth")

team11.set((), "Baseball") team11.set(("name",), "Boston Red Sox") team11.set(("players", "1"), "Babe Ruth")

team2.set((), "Baseball") team2.set(("name",), "New York Yankees") team2.set(("players", "2"), "Lou Gehrig")

Export to dictionaries

data1 = team1.to_dict() data2 = team2.to_dict()

Merge dictionaries

data1.update(data2)

Import merged dictionary

team1.from_dict(data1) prin(team1.zw())

^team1=Baseball

^team1("name")=New York Yankees

^team1("players","1")=Babe Ruth

^team1("players","2")=Lou Gehrig

or

team11.from_dict(team2) prin(team11.zw())

^team11=Baseball

^team11("name")=New York Yankees

^team11("players","1")=Babe Ruth

^team11("players","2")=Lou Gehrig

The benefit of this approach is that it allows you to use Python’s built-in dictionary operations to manipulate globals, making it easier to work with hierarchical data structures.
For the more, no need to build a complex python code to merge two globals.

12. Roadmap

  • Add support for global arrays
  • Add support for byte set/get
  • Add support for listbuild, vector, pva, bit
  • Add support of mutli-dimensional variables

13. Compare to other libraries

This table compares the api of the iris_global library with other libraries, only low-level operations are compared:

Feature iris_global irisnative embedded-python comments
initialize global_reference = GlobalReference("^demo", connection=conn) conn = iris.connect(...); global_reference = iris.createIRIS(conn) global_reference = iris.gref("^demo") omit connection for embedded Python
set value global_reference.set(("name",1), "Boston Red Sox") global_reference.set("Boston Red Sox", "demo", "name", 1) global_reference.set(["name",1], "Boston Red Sox") for irisnative, the value is the first argument
get value global_reference.get(("name",1)) global_reference.get("demo", "name", 1) global_reference.get(["name",1])
check if node exists global_reference.data(("name",1)) global_reference.isDefined("demo", "name", 1) global_reference.data(["name",1])
delete node global_reference.kill(("name",1)) global_reference.kill("demo", "name", 1) global_reference.kill(["name",1])
order global_reference.order(("name",1)) global_reference.nextSubscript(False, "demo", "name", 1) global_reference.order(["name",1]) for irisnative, the reverse flag is the first argument

General remarks:

  • iris_global support for get/set can be used with str, list or tuple subscript
  • irisnative use the value as the first argument
  • embedded-python use list subscript
  • irisnative use nextSubscript instead of order
  • irisnative use isDefined instead of data

14. Testing

Run the test suite:

python -m pytest

15. License

MIT License - see LICENSE for details.

Version
1.0.005 May, 2026
Ideas portal
Category
Technology Example
Works with
InterSystems IRISInterSystems IRIS for HealthHealthShareTrakCare
First published
05 May, 2026
Last edited
05 May, 2026