# Get Data from Dataset "safely"

**URL:** <https://forum.inductiveautomation.com/t/get-data-from-dataset-safely/114057>\
**Category:** Ignition\
**Tags:** scripting\
**Created:** [February 19, 2026, 8:45am UTC](https://forum.inductiveautomation.com/t/get-data-from-dataset-safely/114057 "2026-02-19T08:45:23Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![danielps1818](https://avatars.discourse-cdn.com/v4/letter/d/ecae2f/32.png) [@danielps1818](https://forum.inductiveautomation.com/u/danielps1818)\
**Post date:** [February 19, 2026, 8:45am UTC](https://forum.inductiveautomation.com/t/get-data-from-dataset-safely/114057/1 "2026-02-19T08:45:23Z")

</div>

I have a dataset _(or PyDataset)_.  
I loop throw the data. Something like this:

```python
for row in dataset:
    print row["COLUMN_1"]
    print row["COLUMN_2"]
    print row["COLUMN_3"]
    print row["COLUMN_4"]
    print row["COLUMN_5"]

```

However, any of the columns could not exist (I can't know it.. ). Is there any way of accesing the data safely so it doesn't throw an exception?  
I believe there is not a safe way. I'm really looking for any scripting tip to do it. The idea is to print the row or print 0 if the column doesn't exist.

Thanks!

---

<div class="post-metadata">

**Author:** ![Cose\_Peter1](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/cose_peter1/32/79174_2.png) [@Cose\_Peter1](https://forum.inductiveautomation.com/u/Cose_Peter1)\
**Post date:** [February 19, 2026, 9:47am UTC](https://forum.inductiveautomation.com/t/get-data-from-dataset-safely/114057/2 "2026-02-19T09:47:23Z")

</div>

I don't think there is a straight forward way to do this. Maybe you can use  
**`getColumnNames()`** function and maybe convert it into a set. Then, before printing you just do an

```python
columnNameSet = set(dataset.getColumnNames())
for row in dataset:
	if "COLUMN_1" in columnNameSet:
		print row["COLUMN_1"]
	else:
		print 0

```

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [February 19, 2026, 1:04pm UTC](https://forum.inductiveautomation.com/t/get-data-from-dataset-safely/114057/3 "2026-02-19T13:04:14Z")

</div>

Probably not great for perfomance (haven’t tested on a large ds) you could convert your PyDataset to a list of dicts like

`data = [{column:row[column] for column in ds.getColumnNames()} for row in ds]`

Then you can leverage the dictionary `.get()` method which allows you to provide a key and default return value if it does not exist.

```python
for row in data:
    value = row.get("someColumn", None) # or whatever you want your default value to be if it's not found
    if value is not None:
        # value was found, do something

```

Maybe more pythonic to just try and ask forgiveness

```python
for row in ds:
    try:
        x = row['someOtherColumn']
    except ValueError, e:
        # column did not exist
        print 0

```

> there any way of accesing the data safely so it doesn't throw an exception?

You should get used to handling exceptions instead of just trying to perfectly ask for things imo. It’s the pythonic coding style. Much better to do.

```python
try:
    doSomeTask()
except someError, e:
    # handle error

```

Than to do

```python
if canDoTask():
    doSomeTask()
else:
    handleError()

```

May not seem like it if you’re not used to it but once you get adjusted it makes things very easy to reason about imo. More info [https://stackoverflow.com/questions/12265451/ask-forgiveness-not-permission-explain](https://stackoverflow.com/questions/12265451/ask-forgiveness-not-permission-explain)

---

<div class="post-metadata">

**Author:** ![Lynn\_Martineau](https://avatars.discourse-cdn.com/v4/letter/l/f1d935/32.png) [@Lynn\_Martineau](https://forum.inductiveautomation.com/u/Lynn_Martineau)\
**Post date:** [February 19, 2026, 2:50pm UTC](https://forum.inductiveautomation.com/t/get-data-from-dataset-safely/114057/4 "2026-02-19T14:50:47Z")

</div>

You can get a list of column names in a dataset with:

> `system.dataset.getColumnHeaders(datasetName)`

With the list you can use the logic @Cose_Peter1 provided

---

<div class="post-metadata">

**Author:** ![lane.duncan](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lane.duncan/32/83700_2.png) [@lane.duncan](https://forum.inductiveautomation.com/u/lane.duncan)\
**Post date:** [February 20, 2026, 7:32am UTC](https://forum.inductiveautomation.com/t/get-data-from-dataset-safely/114057/5 "2026-02-20T07:32:04Z")

</div>

This is how I would do it:

```python
	import traceback
	logger = system.util.getLogger("Column Count Test")
	try:
		#Test dataset saved in the root.custom props
		dataset = self.parent.custom.testDataset
		#Get the column count by looking at the length of the header list
		columnCount = len(system.dataset.getColumnHeaders(dataset))
		#Iterate as needed to accomplish the task
		for row in dataset:
			for col in range(columnCount):
				cellData = row[col]
				system.perspective.print(str(cellData))
	except:
		message = traceback.format_exc()
		#Print to the output console
		system.perspective.print(message)
		#Log any show stopping errors to the gateway   
		logger.error(message)

```

I also added in my personal go to error catching method using the traceback library.

If I could remember who showed me the traceback method I would give credit......but I don't remember.

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [February 20, 2026, 8:48am UTC](https://forum.inductiveautomation.com/t/get-data-from-dataset-safely/114057/6 "2026-02-20T08:48:17Z")

</div>

I'd add the missing columns to the dataset:

```python
ds = system.dataset.toDataSet(
	['name', 'val', 'square'],
	[
		[
			"foo_{}".format(n),
			n,
			n*n
		] for n in range(10)
	]
)

columns_to_print = set(('name', 'val', 'something'))
actual_columns = set(ds.columnNames)
missing_columns = columns_to_print - actual_columns

for c in missing_columns:
	ds = system.dataset.addColumn(ds, [0] * ds.rowCount, c, int)

lib.dataset.print_ds(ds)

```

so, basically:

```python
def normalize_ds(ds, columns):
	for c in set(columns) - set(ds.columnNames):
		ds = system.dataset.addColumn(ds, [0] * ds.rowCount, c, int)
	return ds

```

Which could (and probably should) be improved in a multitude of ways:  
Make a "required columns" a dict, or list of dicts, so you can parameterize, for each of them, what its type and default value should be,  
Allow users to chose if they want to keep all existing columns or only what's in the required columns,  
validate the column types,  
etc...

Assuming you want to do more than just printing the ds (in which case I'm not sure why you'd want to display a column full of zeros).  
Also, what should happen to columns that are in the dataset, but not in your column list ?

But what's the use case exactly ?
