I have a situation where I need to have a table updated from Ignition Perspective. I am updating just 1 column and either 1 cell or mutiple cells at the same time.
In the picture attached, the cell to be updated would be the Storage Type.
What is the best way to do this. I have used tables previously but i was only updating 1 field in a column at a time.
I was going to use COLUMN_3 to write the new value
I was also going to use this Action Script:
# Get the selected SKUs from the table
selected_items = self.getSibling("Table").props.selection.data
# Iterate over each selected SKU and update it
for item in selected_items:
sku = item['sku']
storage_type = item['storage_type']
category = "HMI"
source = "ASCADA Client"
usr = self.session.props.auth.user.id
message = f"{usr} Updated {sku} Storage Type WCS {storage_type}"
data9 = usr
# Insert or update SKU
system.db.runNamedQuery("Tables/update_sku_table", {
"sku": sku,
"storage_type": storage_type
})
time.sleep(2)
# Update Syslog
system.db.runNamedQuery("Tables/syslog_update", {
"category": category,
"source": source,
"message": message,
"data9": data9
})
time.sleep(2)
# Refresh table data after updating all SKUs
self.getSibling("Table").refreshBinding("props.data")
time.sleep(2)
Some general tips with writing db queries here - you do not need to time.sleep(2) to wait for the query to finish or anything like that. If you are worried about one query running and the other one not running, use transactions.
message = f"{usr} Updated {sku} Storage Type WCS {storage_type}" this won't work, there are no f-strings in jython 2.7. If it seems like nothing is happening database wise then its probably because the script is hitting an error on this line.
I don't know exactly what data you get from selection.data but seems a reasonable choice if you only want to affect the selected rows though I can't speak to if your syntax is right or wrong on that.
Yep and as you are not doing anything with the return from the call to system.db.runNamedQuery() the only thing this is doing is slowing down your performance dramatically. system.db.runNamedQuery() is a blocking function so it will automatically wait for a return before executing the next call anyway.
You can do this however:
message = "{} Updated {} Storage Type WCS {}".format(usr,sku,storage_type)
Alternatively, you can use an onEditCellCommit event on the table to then update the row.
Mind the if statement so that you only run the named query if the column that was updated is indeed column_2, or whatever your column name is for storage type.
def runAction(self, event):
sku = self.props.data[event.row].column_1
# Update Storage Type
# Assuming column name is column_2 for Storage Type
if event.column == 'column_2':
storage_type = event.value
# Insert or update SKU
path = "Tables/update_sku_table"
parameters = {"sku": sku, "storage_type": storage_type}
system.db.runNamedQuery(path, parameters)
self.refreshBinding('props.data')
Named Query
UPDATE [yourTable]
SET [StorageType] = :storage_type
WHERE [SKU] = :sku
I am back at this morning and I am having some issues that I am sure are basic.
First, I am trying a query to onEditCellCommit but i am unsure who to make it work. I need the select query to populate the table but I also need an update query. How do i populate the table and do an update as the same query?
I was working with the table this morning and the table will not allow me to change the storage type. When I edit it, it goes back to the original.
As a note, i am trying to update a mysql table from this ignition table.
Second, when I add another column that I want to pull the data from it does not let me edit that cell. I have everything set properly but i cannot click to edit.
If it would be easier I could use onEditCellCommit but i do not know how to write that.
I see how to add it to the script but not sure if it is correct.
`def runAction(self, event):
# Get the id of the row we edited.
id = self.data.getValueAt(rowIndex, 'ID')
# Create our query and arguments. The extension function gives us a colName variable,
# which we can use in our query. The query will then take two arguments.
# The value that we are updating and the id of the row we edited.
query = "UPDATE material_master SET %s = ? WHERE storage_type = ?" % (storage_type)
args = [newValue, id]
# Run the query with the specified arguments.
system.db.runPrepUpdate(query, args)
# Re-query the database, so we can ensure it properly updated the table.
system.db.refresh(self, "data")`
Why? It's a forum, literally a platform for asking questions.
I would expect code something like this:
#assuming that props.data is a dataset
rowId = self.props.data.getValueAt(event.row, "ID")
#if props.data is in JSON format then it would be
#rowId = self.props.data[event.row]["ID"]
#update database with edited data.
query = "UPDATE material_master SET {} = ? WHERE storage_type = ?".format(event.column)
args = [event.value, rowId]
system.db.runPrepUpdate(query,args)
#refresh the binding on props.data to pull in the edited data.
self.refreshBinding('props.data')
Unable to run action 'component.onEditCellCommit' on Popups/MHS Converted/Storage Type Pass Through@D/root/Table_0: code could not be compiled.
com.inductiveautomation.ignition.common.script.JythonExecException
Traceback (most recent call last):
File "<function:runAction>", line 8, in <module>
NameError: name 'event' is not defined
caused by org.python.core.PyException
Traceback (most recent call last):
File "<function:runAction>", line 8, in <module>
NameError: name 'event' is not defined
Ignition v8.1.33 (b2023101913)
Java: Azul Systems, Inc. 17.0.8
def runAction(self, event):
#assuming that props.data is a dataset
rowId = self.props.data.getValueAt(event.row, "ID")
#if props.data is in JSON format then it would be
#rowId = self.props.data[event.row]["ID"]
#update database with edited data.
query = "UPDATE material_master SET {} = ? WHERE storage_type = ?".format(event.column)
args = [event.value, rowId]
system.db.runPrepUpdate(query,args)
#refresh the binding on props.data to pull in the edited data.
self.refreshBinding('props.data')
com.inductiveautomation.ignition.common.script.JythonExecException
Traceback (most recent call last):
File "<function:runAction>", line 3, in runAction
java.lang.ArrayIndexOutOfBoundsException: java.lang.ArrayIndexOutOfBoundsException: Column 'ID' doesn't exist in this dataset.
caused by org.python.core.PyException
Traceback (most recent call last):
File "<function:runAction>", line 3, in runAction
java.lang.ArrayIndexOutOfBoundsException: java.lang.ArrayIndexOutOfBoundsException: Column 'ID' doesn't exist in this dataset.
caused by ArrayIndexOutOfBoundsException: Column 'ID' doesn't exist in this dataset.
Ignition v8.1.33 (b2023101913)
Java: Azul Systems, Inc. 17.0.8
The error is telling you exactly what the issue is. There is not an "ID" column in the props.data dataset on the table. Either change the way the table is being populated to include the "ID" column or use the correct column name to get the rowId.
com.inductiveautomation.ignition.common.script.JythonExecException
Traceback (most recent call last):
File "<function:runAction>", line 8, in <module>
NameError: name 'event' is not defined
caused by org.python.core.PyException
Traceback (most recent call last):
File "<function:runAction>", line 8, in <module>
NameError: name 'event' is not defined
Ignition v8.1.33 (b2023101913)
Java: Azul Systems, Inc. 17.0.8