# Jython Script to read Internal Database using javadocs

**URL:** <https://forum.inductiveautomation.com/t/jython-script-to-read-internal-database-using-javadocs/86777>\
**Category:** Ignition\
**Tags:** ignition79\
**Created:** [March 4, 2024, 4:51pm UTC](https://forum.inductiveautomation.com/t/jython-script-to-read-internal-database-using-javadocs/86777 "2024-03-04T16:51:27Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![CJ\_Johnson](https://avatars.discourse-cdn.com/v4/letter/c/b77776/32.png) [@CJ\_Johnson](https://forum.inductiveautomation.com/u/CJ_Johnson)\
**Post date:** [March 4, 2024, 4:51pm UTC](https://forum.inductiveautomation.com/t/jython-script-to-read-internal-database-using-javadocs/86777/1 "2024-03-04T16:51:27Z")

</div>

My team currently has an automation setup to quickly add devices to gateways but we need a way to query the list of configured devices and their connection paths and other parameters.

As of now, I can access the the parameters I need by manually running SQL queries via the web UI @ main/web/status/sys.internaldb?10

Example of the queries  
DEVICESETTINGS.NAME as name,  
LOGIXDRIVERSETTINGS.HOSTNAME as logix\_hostname,  
COMPACTLOGIXDRIVERSETTINGS.HOSTNAME as compactlogix\_hostname,  
CONTROLLOGIXDRIVERSETTINGS.HOSTNAME as controllogix\_hostname,  
S71500DRIVERSETTINGS.HOSTNAME as siemens\_hostname,  
LOGIXDRIVERSETTINGS.SLOTNUMBER as logix\_slot,

I have many gateways to go through and automating this effort would be great.

Is there a way to read tables off the internal database and use the result in a Jython script using the javadocs?

For example for the devicesettings table, I would want to iterate over each device on the gateway and record the following fields (description, enable, general,id,name,type) described here. [ignition 7.9.5 API](https://files.inductiveautomation.com/sdk/javadoc/ignition79/795/index.html)  
com.inductiveautomation.xopc.driver.api.configuration.DeviceSettingsRecord

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [March 4, 2024, 4:55pm UTC](https://forum.inductiveautomation.com/t/jython-script-to-read-internal-database-using-javadocs/86777/2 "2024-03-04T16:55:48Z")

</div>

There's no _supported_ way to access the internal database at runtime, but there's some methods floating around the forum. Start from the `PersistenceInterface` class.

---

<div class="post-metadata">

**Author:** ![CJ\_Johnson](https://avatars.discourse-cdn.com/v4/letter/c/b77776/32.png) [@CJ\_Johnson](https://forum.inductiveautomation.com/u/CJ_Johnson)\
**Post date:** [March 4, 2024, 6:33pm UTC](https://forum.inductiveautomation.com/t/jython-script-to-read-internal-database-using-javadocs/86777/3 "2024-03-04T18:33:40Z")

</div>

I'm aware that my ask is not officially supported.  
I can't quite find a post that mirrors what I'm attempting. Most examples I've seen are java solutions while I'm looking for Python/Jython.

From what I've read, I came up with this

```auto
from com.inductiveautomation.ignition.gateway import SRContext
from com.inductiveautomation.xopc.driver.api.configuration import DeviceSettingsRecord
import simpleorm.dataset.SQuery as SQuery
import simpleorm.dataset.SRecordMeta as SRecordMeta

def run():
	query = SQuery(DeviceSettingsRecord.META).ascending(DeviceSettingsRecord.Name)
	results = SRContext.get().getPersistenceInterface().query(query)
	test = []
	for result in results:
		test.append(result.getName())
	logger.info("%s" % (test))
	return test

```

I'm trying to run this from the gw but keep getting errors trying to import DeviceSettingsRecord.

```auto
com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last): File "", line 9, in ImportError: Error loading module getNames: Traceback (most recent call last): File "", line 2, in ImportError: No module named xopc
at org.python.core.Py.ImportError(Py.java:304)

```

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [March 4, 2024, 6:39pm UTC](https://forum.inductiveautomation.com/t/jython-script-to-read-internal-database-using-javadocs/86777/4 "2024-03-04T18:39:04Z")

</div>

Most PI record implementations are module-specific, and can only be obtained when in that module's classloader environment. So, the OPC UA server module for `DeviceSettingsRecord` itself, and each driver module for their driver-specific extension records.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [March 4, 2024, 6:45pm UTC](https://forum.inductiveautomation.com/t/jython-script-to-read-internal-database-using-javadocs/86777/5 "2024-03-04T18:45:12Z")

</div>

On the gateway, modules are each in separate, segmented classloaders, so you won't easily be able to retrieve instances of module specific classes. You're probably better off with a 'raw' query - you'll have to open a session in your code (make sure you close it!) and then call one of the methods that returns a dictionary or list of dictionaries:

> **[SSessionJdbc](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.37/simpleorm/sessionjdbc/SSessionJdbc.html#rawQueryMap(java.lang.String,boolean,java.lang.Object...))**
>
> declaration: package: simpleorm.sessionjdbc, class: SSessionJdbc

---

<div class="post-metadata">

**Author:** ![CJ\_Johnson](https://avatars.discourse-cdn.com/v4/letter/c/b77776/32.png) [@CJ\_Johnson](https://forum.inductiveautomation.com/u/CJ_Johnson)\
**Post date:** [March 4, 2024, 7:23pm UTC](https://forum.inductiveautomation.com/t/jython-script-to-read-internal-database-using-javadocs/86777/6 "2024-03-04T19:23:34Z")

</div>

Would you be able to assist with the proper syntax for the raw query? I'm not sure how to proceed.

I would have to import

```auto
import simpleorm.dataset.SSessionI as SSession

```

than something like this?

```auto
query = SSession.query(SELECTDEVICESETTINGS.NAME as name)

```

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [March 4, 2024, 7:33pm UTC](https://forum.inductiveautomation.com/t/jython-script-to-read-internal-database-using-javadocs/86777/7 "2024-03-04T19:33:54Z")

</div>

No, you cannot use `.query()` without the ORM classes. You must use one of the `.rawQuery*()` methods.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [March 4, 2024, 8:17pm UTC](https://forum.inductiveautomation.com/t/jython-script-to-read-internal-database-using-javadocs/86777/8 "2024-03-04T20:17:10Z")

</div>

PersistenceInterface has a method on it to open a session, which will be an instance of the session class you call the raw query method on.

---

<div class="post-metadata">

**Author:** ![CJ\_Johnson](https://avatars.discourse-cdn.com/v4/letter/c/b77776/32.png) [@CJ\_Johnson](https://forum.inductiveautomation.com/u/CJ_Johnson)\
**Post date:** [March 4, 2024, 8:18pm UTC](https://forum.inductiveautomation.com/t/jython-script-to-read-internal-database-using-javadocs/86777/9 "2024-03-04T20:18:39Z")

</div>

I've now tried the following

```auto
from com.inductiveautomation.ignition.gateway import SRContext
from simpleorm.dataset import SSessionI

def run():
	query = SRContext.get().getPersistenceInterface().getSession()
	try:
		query.rawQueryMaps("SELECT DEVICESETTINGS.NAME FROM from DEVICESETTINGS", True, [])
	finally:
		    query.close()
	test = []
	for quer in query:
		test.append(quer.getName())
	logger.info("%s" % (test))
	return test

```

Which returns :

```auto
com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last): File "", line 9, in File "", line 7, in run at simpleorm.sessionjdbc.SSessionJdbc.rawQueryInner(SSessionJdbc.java:797) at simpleorm.sessionjdbc.SSessionJdbc.rawQueryMaps(SSessionJdbc.java:709) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) simpleorm.utils.SException$Jdbc: simpleorm.utils.SException$Jdbc: org.sqlite.SQLiteException: [SQLITE_ERROR] SQL error or missing database (near "from": syntax error) 

```

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [March 4, 2024, 8:21pm UTC](https://forum.inductiveautomation.com/t/jython-script-to-read-internal-database-using-javadocs/86777/10 "2024-03-04T20:21:35Z")

</div>

> [@CJ\_Johnson](#):
>
> `FROM from`

Typo in your query?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [March 4, 2024, 8:31pm UTC](https://forum.inductiveautomation.com/t/jython-script-to-read-internal-database-using-javadocs/86777/11 "2024-03-04T20:31:21Z")

</div>

I don't see you closing the session, either. Danger!

---

<div class="post-metadata">

**Author:** ![CJ\_Johnson](https://avatars.discourse-cdn.com/v4/letter/c/b77776/32.png) [@CJ\_Johnson](https://forum.inductiveautomation.com/u/CJ_Johnson)\
**Post date:** [March 4, 2024, 8:38pm UTC](https://forum.inductiveautomation.com/t/jython-script-to-read-internal-database-using-javadocs/86777/12 "2024-03-04T20:38:56Z")

</div>

Does the line query.close the session? I have it there.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [March 4, 2024, 8:39pm UTC](https://forum.inductiveautomation.com/t/jython-script-to-read-internal-database-using-javadocs/86777/13 "2024-03-04T20:39:43Z")

</div>

Ah, yes. You called it `query` instead of `session`.

---

<div class="post-metadata">

**Author:** ![CJ\_Johnson](https://avatars.discourse-cdn.com/v4/letter/c/b77776/32.png) [@CJ\_Johnson](https://forum.inductiveautomation.com/u/CJ_Johnson)\
**Post date:** [March 4, 2024, 8:41pm UTC](https://forum.inductiveautomation.com/t/jython-script-to-read-internal-database-using-javadocs/86777/14 "2024-03-04T20:41:49Z")

</div>

I now have the following.

```auto
def run():
	logger = LoggerFactory.getLogger(LOGGER_PREFIX + "run")
	query = SRContext.get().getPersistenceInterface().getSession()
	try:
		query.rawQueryMaps("SELECT DEVICESETTINGS.NAME FROM DEVICESETTINGS", True, [])
	finally:
		    query.close()
	logger.info("%s" % (query))

```

This does not error but the output is unexpected.

 ![Screenshot 2024-03-04 at 3.37.35 PM](https://us1.discourse-cdn.com/inductiveautomation/original/3X/9/1/91bb8f19cf28827702219265e646d084f25d7a07.png)

Would "query" hold the dataset created by rawQueryMaps?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [March 4, 2024, 8:44pm UTC](https://forum.inductiveautomation.com/t/jython-script-to-read-internal-database-using-javadocs/86777/15 "2024-03-04T20:44:34Z")

</div>

You didn't capture the return value from `.rawQueryMaps()`. And it isn't a dataset. It's a list of maps (dictionaries).

---

<div class="post-metadata">

**Author:** ![CJ\_Johnson](https://avatars.discourse-cdn.com/v4/letter/c/b77776/32.png) [@CJ\_Johnson](https://forum.inductiveautomation.com/u/CJ_Johnson)\
**Post date:** [March 4, 2024, 8:54pm UTC](https://forum.inductiveautomation.com/t/jython-script-to-read-internal-database-using-javadocs/86777/16 "2024-03-04T20:54:12Z")

</div>

I finally have an output containing the values I expected. I can scale this up gather the other parameters I need. Thank you to all who chimed in. I truly appreciate the help I've received today.

---

<div class="post-metadata">

**Author:** ![tyler.bennett](https://avatars.discourse-cdn.com/v4/letter/t/f04885/32.png) [@tyler.bennett](https://forum.inductiveautomation.com/u/tyler.bennett)\
**Post date:** [October 29, 2025, 8:06am UTC](https://forum.inductiveautomation.com/t/jython-script-to-read-internal-database-using-javadocs/86777/17 "2025-10-29T08:06:54Z")

</div>

Thanks to all who contributed in this thread.  
The clues herein led me to develop a solution (unsupported as it may be) for reading all properties for existing devices (Ignition v8.1). Posted here:

> [@How to read properties of existing device connection - Example Code](https://forum.inductiveautomation.com/t/how-to-read-properties-of-existing-device-connection-example-code/111772):
>
> I had often been disappointed that not all device connection properties for existing devices were easily available through supported scripting (system.device.listDevices()) . I recently had cause to develop a methodology to create/update/remove devices, UDTs (definitions/instances), tags and tag alarms based on an Excel workbook. Without scripted access to device connection properties it was difficult to determine whether a device required an update so I dug in and finally found a way to retriev…
