# Perspective Table to CSV download - Random Error

**URL:** <https://forum.inductiveautomation.com/t/perspective-table-to-csv-download-random-error/94619>\
**Category:** Ignition\
**Tags:** perspective, ignition81, scripting\
**Created:** [August 13, 2024, 10:58pm UTC](https://forum.inductiveautomation.com/t/perspective-table-to-csv-download-random-error/94619 "2024-08-13T22:58:27Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![r123](https://avatars.discourse-cdn.com/v4/letter/r/838e76/32.png) [@r123](https://forum.inductiveautomation.com/u/r123)\
**Post date:** [August 13, 2024, 10:58pm UTC](https://forum.inductiveautomation.com/t/perspective-table-to-csv-download-random-error/94619/1 "2024-08-13T22:58:27Z")

</div>

I have a script that worked until today. I thought maybe it was because of the number of pages in the table but I populated the table with a different larger date range, giving me a CSV with 45K rows from a table with hundreds of pages.

The range with the issue is only 21 pages but the script fails with this error.

`line 13, in runAction TypeError: Unable to convert row 1, column 4 to type class java.lang.Long`

The 4th column in the table is always a string so not sure what would cause this. The data is all very similar, regardless of the date range.

```python
def runAction(self, event):
    # root > table-flex > body > table
    table = self.parent.parent.getChild("Table")
    
    # create a list of columns that are selected by user
    colsToKeep = [col["field"] for col in table.props.columns if col["visible"]]
    
    data = []
    for el in table.props.data:
        rowData = [el[col] for col in colsToKeep if col in el]
        data.append(rowData)
    
    newCsv = system.dataset.toCSV(system.dataset.toDataSet(colsToKeep, data))
    
    # Get the date from DateTimeInput_Start component
    raw_date = self.parent.parent.getChild("FlexContainer_Date_Range").getChild("DateTimeInput_Start").props.value
    
    # Convert the raw_date to a formatted string
    formatted_date = system.date.format(system.date.parse(raw_date), "yyyy-MM-dd HH:mm:ss")
    
    # Replace characters in formatted_date to make it filename-friendly
    filename_date = formatted_date.replace(":", "-").replace(" ", "_")
    
    # Create the filename
    filename = "Azure_Export_" + filename_date + ".csv"
    
    # Trigger the download
    system.perspective.download(filename, newCsv)

```

---

<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:** [August 13, 2024, 11:02pm UTC](https://forum.inductiveautomation.com/t/perspective-table-to-csv-download-random-error/94619/2 "2024-08-13T23:02:06Z")

</div>

Row and column numbering is zero-based, so look at the **fifth** column.

---

<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:** [August 13, 2024, 11:04pm UTC](https://forum.inductiveautomation.com/t/perspective-table-to-csv-download-random-error/94619/3 "2024-08-13T23:04:58Z")

</div>

> [@r123](#):
>
> `rowData = [el[col] for col in colsToKeep if col in el]`

Actually, this will not yield a consistent length. Should probably be:

```python
rowData = [el.get(col) for col in colsToKeep]

```

That will put nulls in the list when a key is missing from `props.data` on a particular row.

---

<div class="post-metadata">

**Author:** ![r123](https://avatars.discourse-cdn.com/v4/letter/r/838e76/32.png) [@r123](https://forum.inductiveautomation.com/u/r123)\
**Post date:** [August 13, 2024, 11:35pm UTC](https://forum.inductiveautomation.com/t/perspective-table-to-csv-download-random-error/94619/4 "2024-08-13T23:35:15Z")

</div>

Good to know, the error always says row 1 so I was thinking it was not zero-based. The fifth column is a value. Most always a float but a few are Integers or Boolean.

I tried filtering the range by a few different types in the second column and the script worked every time.

---

<div class="post-metadata">

**Author:** ![r123](https://avatars.discourse-cdn.com/v4/letter/r/838e76/32.png) [@r123](https://forum.inductiveautomation.com/u/r123)\
**Post date:** [August 13, 2024, 11:36pm UTC](https://forum.inductiveautomation.com/t/perspective-table-to-csv-download-random-error/94619/5 "2024-08-13T23:36:49Z")

</div>

After making this change it now says the issue is on row two.

```python

line 13, in runAction TypeError: Unable to convert row 2, column 4 to type class java.lang.Long

```

---

<div class="post-metadata">

**Author:** ![r123](https://avatars.discourse-cdn.com/v4/letter/r/838e76/32.png) [@r123](https://forum.inductiveautomation.com/u/r123)\
**Post date:** [August 13, 2024, 11:49pm UTC](https://forum.inductiveautomation.com/t/perspective-table-to-csv-download-random-error/94619/6 "2024-08-13T23:49:47Z")

</div>

This is a little odd. It just worked but when I ran it again it now says row (3) four is the issue.

In the current table this first 5 rows all have a value of 0. Not sure if the CSV is created in the current order of the table.

![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/a/2/a26078c8cb6652553905f25ab00cb942705e0520.png)

---

<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:** [August 13, 2024, 11:51pm UTC](https://forum.inductiveautomation.com/t/perspective-table-to-csv-download-random-error/94619/7 "2024-08-13T23:51:11Z")

</div>

Perhaps you should show the first several rows of your data.

Keep in mind that `system.dataset.toDataSet()` determines the column types of the output dataset from the **first** row of the input. If anything changes type after the first row, breakage is likely.

---

<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:** [August 13, 2024, 11:52pm UTC](https://forum.inductiveautomation.com/t/perspective-table-to-csv-download-random-error/94619/8 "2024-08-13T23:52:21Z")

</div>

If you need precise control over column types (I usually do), use the `DatasetBuilder` instead.

---

<div class="post-metadata">

**Author:** ![r123](https://avatars.discourse-cdn.com/v4/letter/r/838e76/32.png) [@r123](https://forum.inductiveautomation.com/u/r123)\
**Post date:** [August 14, 2024, 2:11pm UTC](https://forum.inductiveautomation.com/t/perspective-table-to-csv-download-random-error/94619/9 "2024-08-14T14:11:56Z")

</div>

I'm still testing but even if I leave the range the same and only update the table from the Azure DB it will randomly work. It looks like all the same values or rows are there each time but in a different order. The error message will change the row number it has the error on. So just the order of rows in the table seems to cause the error. But the table always seems ok.

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [August 14, 2024, 2:37pm UTC](https://forum.inductiveautomation.com/t/perspective-table-to-csv-download-random-error/94619/10 "2024-08-14T14:37:56Z")

</div>

> [@r123](#):
>
> it will randomly work. It looks like all the same values or rows are there each time but in a different order. The error message will change the row number it has the error on

This still sounds like python duck typing is getting in the way.

As an example, say you have a first row where a column value is 1.3, the script will then use float as the column type, if in a following row that column has a value of 0 you’ll get an error because it would be trying to insert an integer into a float column.

Look into the Dataset Builder as @pturmel suggests.

---

<div class="post-metadata">

**Author:** ![r123](https://avatars.discourse-cdn.com/v4/letter/r/838e76/32.png) [@r123](https://forum.inductiveautomation.com/u/r123)\
**Post date:** [August 28, 2024, 8:45pm UTC](https://forum.inductiveautomation.com/t/perspective-table-to-csv-download-random-error/94619/11 "2024-08-28T20:45:27Z")

</div>

I was able to update the make CSV function to work where the original did not. The script now checks for int, float, and long types and casts them to float. Seems to work so far.

```python
def runAction(self, event):
    # root > table-flex > body > table
    table = self.parent.parent.getChild("Table")
    
    # Create a list of columns that are selected by user
    colsToKeep = [col["field"] for col in table.props.columns if col["visible"]]
    
    # Prepare data for dataset
    data = []
    for el in table.props.data:
        rowData = []
        for col in colsToKeep:
            value = el.get(col)
            if isinstance(value, (int, float, long)): # Ensure all numeric types are consistent
                value = float(value)
            rowData.append(value)
        data.append(rowData)
    
    # Create the dataset manually
    newDataSet = system.dataset.toDataSet(colsToKeep, data)
    newCsv = system.dataset.toCSV(newDataSet)
    
    # Get the date from DateTimeInput_Start component
    raw_date = self.parent.parent.getChild("FlexContainer_Date_Range").getChild("DateTimeInput_Start").props.value
    
    # Convert the raw_date to a formatted string
    formatted_date = system.date.format(system.date.parse(raw_date), "yyyy-MM-dd HH:mm:ss")
    
    # Replace characters in formatted_date to make it filename-friendly
    filename_date = formatted_date.replace(":", "-").replace(" ", "_")
    
    # Create the filename
    filename = "Azure_Export_" + filename_date + ".csv"
    
    # Trigger the download
    system.perspective.download(filename, newCsv)

```
