# Help with system.tag.queryTagHistory

**URL:** <https://forum.inductiveautomation.com/t/help-with-system-tag-querytaghistory/31000>\
**Category:** Ignition\
**Created:** [January 1, 2020, 6:06am UTC](https://forum.inductiveautomation.com/t/help-with-system-tag-querytaghistory/31000 "2020-01-01T06:06:47Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![dfraker](https://avatars.discourse-cdn.com/v4/letter/d/90db22/32.png) [@dfraker](https://forum.inductiveautomation.com/u/dfraker)\
**Post date:** [January 1, 2020, 6:06am UTC](https://forum.inductiveautomation.com/t/help-with-system-tag-querytaghistory/31000/1 "2020-01-01T06:06:47Z")

</div>

I am running the following code:  
endTime = system.date.now()  
startTime = system.date.addDays(endTime, -1)  
tubingPath = ‘Athena 1H/WellHead/Tubing’  
tubingSet = system.tag.queryTagHistory(paths=[tubingPath], startDate=startTime, endDate=endTime, intervalMinutes=1, aggregationMode=“LastValue”, returnFormat=‘Tall’)

When I select a start time greater than 6 days, or 166 hours it fails. I’ve tried several different variations to select the dates, but I’ve had no luck.  
This is the error I receive and for reference, line 14 is where I use the dataset. It acts like anything after 6 days is out of bounds and doesn’t pull the tag history.

Error:  
Traceback (most recent call last):

File “event:actionPerformed”, line 14, in

AttributeError: ‘com.inductiveautomation.ignition.client.gateway\_in’ object has no attribute ‘data’

Ignition v7.9.9 (b2018081621)  
Java: Oracle Corporation 1.8.0\_211

---

<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:** [January 2, 2020, 4:50pm UTC](https://forum.inductiveautomation.com/t/help-with-system-tag-querytaghistory/31000/2 "2020-01-02T16:50:14Z")

</div>

Can you post your entire script? The limited section you posted doesn’t indicate what could be the problem.

You may also get more info by printing the `type()` of whatever object you’re trying to retrieve the `.data` attribute of - it’s cut off in the error message, but it’s _probably_ a client/gateway exception object.

Check the gateway logs when you run these long queries - you may be getting an error logged there at the same time.

---

<div class="post-metadata">

**Author:** ![dfraker](https://avatars.discourse-cdn.com/v4/letter/d/90db22/32.png) [@dfraker](https://forum.inductiveautomation.com/u/dfraker)\
**Post date:** [January 2, 2020, 5:09pm UTC](https://forum.inductiveautomation.com/t/help-with-system-tag-querytaghistory/31000/3 "2020-01-02T17:09:29Z")

</div>

I don’t see anything helpful to me in the logs when I run this script. In an effort to get it working I tried hours. It will work at 166 hours, but not anything greater. Here is the full script, and the full error. Thanks for the help.

```auto
tubingDS = []
tubingCount = 0

endTime = system.date.now()
#endTime = event.source.parent.getComponent('Date Range').endDate
startTime = system.date.addHours(endTime, -166)
#startTime = event.source.parent.getComponent('Date Range').startDate
tubingPath = "[MSSQL]"+event.source.parent.getComponent('Dropdown').selectedStringValue + '/WellHead/Tubing'
tubingSet = system.tag.queryTagHistory(paths=[tubingPath], intervalMinutes=1, rangeHours=-166, aggregationMode="LastValue", returnFormat='Tall', timeout=60000)
tubingWell = []
casingPath = "[MSSQL]"+event.source.parent.getComponent('Dropdown').selectedStringValue + '/WellHead/Casing'
casingSet = system.tag.queryTagHistory(paths=[casingPath], intervalMinutes=1, rangeHours=-166, aggregationMode="LastValue", returnFormat='Tall', timeout=60000)

for well in tubingSet.data[0]:
	wellStr = str(well)
	wellName = wellStr[:(len(wellStr)-16)]
	tubingWell.append(wellName)

tubingValue = []
for tvalues in tubingSet.data[1]:
	tubingValue.append(tvalues)

tubingDate = []
for dates in tubingSet.data[3]:
	tubingDate.append(dates)

casingValue = []
for cvalues in casingSet.data[1]:
	casingValue.append(cvalues)
	
tubingLen = len(tubingDate)
tubingDS = []
tubingCount = 0
ovr = event.source.parent.getComponent('Numeric Text Field').floatValue
for each in tubingWell:
	if tubingCount < tubingLen:
		wells = tubingWell[tubingCount]
		valuest = tubingValue[tubingCount]
		valuesc = casingValue[tubingCount]
		dates = tubingDate[tubingCount]
		combined = [wells, valuest, valuesc, dates]
		if valuest < ovr:
			tubingDS.append(combined)
	tubingCount += 1 

header = ["Well Name", "Tubing", "Casing", "DateTime"]
combinedDS = system.dataset.toDataSet(header, tubingDS)
comboDS = event.source.parent.getComponent('rawdata').data
comboData = system.dataset.appendDataset(combinedDS, comboDS)
event.source.parent.getComponent('rawdata').data = comboData

```

```auto
Traceback (most recent call last):
  File "<event:actionPerformed>", line 14, in <module>
AttributeError: 'com.inductiveautomation.ignition.client.gateway_in' object has no attribute 'data'

	at org.python.core.Py.AttributeError(Py.java:173)
	at org.python.core.PyObject.noAttributeError(PyObject.java:930)
	at org.python.core.PyObject. __getattr__ (PyObject.java:925)
	at org.python.pycode._pyx25.f$0(<event:actionPerformed>:50)
	at org.python.pycode._pyx25.call_function(<event:actionPerformed>)
	at org.python.core.PyTableCode.call(PyTableCode.java:165)
	at org.python.core.PyCode.call(PyCode.java:18)
	at org.python.core.Py.runCode(Py.java:1275)
	at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:636)
	at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.runActions(ActionAdapter.java:180)
	at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.invoke(ActionAdapter.java:271)
	at com.inductiveautomation.factorypmi.application.binding.action.RelayInvocationHandler.invoke(RelayInvocationHandler.java:57)
	at com.sun.proxy.$Proxy30.actionPerformed(Unknown Source)
	at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
	at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
	at java.awt.Component.processMouseEvent(Unknown Source)
	at javax.swing.JComponent.processMouseEvent(Unknown Source)
	at java.awt.Component.processEvent(Unknown Source)
	at java.awt.Container.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$500(Unknown Source)
	at java.awt.EventQueue$3.run(Unknown Source)
	at java.awt.EventQueue$3.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue$4.run(Unknown Source)
	at java.awt.EventQueue$4.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)

Ignition v7.9.9 (b2018081621)
Java: Oracle Corporation 1.8.0_211

```

---

<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:** [January 2, 2020, 5:15pm UTC](https://forum.inductiveautomation.com/t/help-with-system-tag-querytaghistory/31000/4 "2020-01-02T17:15:09Z")

</div>

Can you add  
`print type(tubingSet)`  
right before the line that’s erroring:  
`for well in tubingSet.data[0]:`

---

<div class="post-metadata">

**Author:** ![dfraker](https://avatars.discourse-cdn.com/v4/letter/d/90db22/32.png) [@dfraker](https://forum.inductiveautomation.com/u/dfraker)\
**Post date:** [January 2, 2020, 5:33pm UTC](https://forum.inductiveautomation.com/t/help-with-system-tag-querytaghistory/31000/5 "2020-01-02T17:33:23Z")

</div>

when it works \< 167 it shows \<type ‘com.inductiveautomation.ignition.common.BasicDataset’\>

when it fails \>167 it shows \<type ‘com.inductiveautomation.ignition.client.gateway\_interface.OptimizedDataSet’\>

---

<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:** [January 2, 2020, 5:52pm UTC](https://forum.inductiveautomation.com/t/help-with-system-tag-querytaghistory/31000/6 "2020-01-02T17:52:11Z")

</div>

Ah, okay, that makes sense.  
So, there’s some ‘magic’ happening here that makes things more inscrutable.  
When you write `tubingSet.data[0]` in Jython, you’re actually calling, Java-wise, `tubingSet.getData()[0]` - but, the [`Dataset`](http://files.inductiveautomation.com/sdk/javadoc/ignition79/795/com/inductiveautomation/ignition/common/Dataset.html) _interface_ doesn’t define a `getData` method - you’re _supposed_ to directly iterate over the rows with a (non-pythonic) sequential getter, like:

```auto
for i in range(tubingSet.rowCount): #can also be `tubingSet.getRowCount()`
    row = tubingSet.getValueAt(i, "some_column")

```

To make things “more Pythonic”, we created “PyDatasets”, which you can convert any dataset into by calling the [`system.dataset.toPyDataset()`](https://docs.inductiveautomation.com/display/DOC80/system.dataset.toPyDataSet) function.

Using PyDatasets is the recommended way to iterate over datasets - using the `data` attribute as you have is relying on [`BasicDataset`](http://files.inductiveautomation.com/sdk/javadoc/ignition79/795/com/inductiveautomation/ignition/common/BasicDataset.html)'s data method, which returns a 2d array (list of lists, if you’re used to Python) of all the data inside the dataset.

The reason you _don’t_ get a `BasicDataset` when you go over a certain number of rows in the query is that we’re attempting to optimize things. The “Optimized” dataset is automatically used when your query goes over, I believe, 10,000 rows - with an optimized dataset, query results are “streamed” to the client piecemeal, instead of the gateway retrieving all the results, serializing them into a single message, and sending that to the client as one value. Optimized datasets conform to the dataset _interface_, but lack the `data` attribute that `BasicDataset`s have.

---

<div class="post-metadata">

**Author:** ![dfraker](https://avatars.discourse-cdn.com/v4/letter/d/90db22/32.png) [@dfraker](https://forum.inductiveautomation.com/u/dfraker)\
**Post date:** [January 9, 2020, 10:53pm UTC](https://forum.inductiveautomation.com/t/help-with-system-tag-querytaghistory/31000/7 "2020-01-09T22:53:52Z")

</div>

This worked great, thanks. The explanation makes a lot of sense.
