Hi all,
I'm uploading JPEG files to a DB using system.db.runPrepUpdate queries from an onFileReceived action on an upload component.
If I just run the query straight from the upload component, it will insert into the DB perfectly and I'm able to retrieve the data, encode it to base 64 then display it on an image component. On the DB the VARBINARY(MAX) looks like this: 0xFFD8FFE000144A46...
However the image data is send through the websocket, so any image larger than the default 2mb will crash the session. I'm not a fan of increasing the websocket limit either, I'd rather use WebDev to send the larger files to the DB.
Using WebDev, my workflow for this problem is as follows:
- (onFileReceived) Using the upload file component, get the filedata of the JPEG image as bytes
- (onFileReceived) Execute an INSERT query to the images table and retrieve the primary key (id)
- (WebDev) Use HTTP doPut with an internal UPDATE query to add the image bytes into the DB.
This is the onFileRecieved action for the upload component:
#get the params from the file component
filedata = event.file.getBytes()
#run the query to insert the image into the DB and return the new ID use run prep update
query = "INSERT INTO [dbo].[images] (id) OUTPUT INSERTED.id VALUES (NEWID());"
db = "SEQIGN01_sw_leviathanCoasterInspection"
imageId = system.db.runQuery(query, db).getValueAt(0,0)
#Set the text field to the ID of the image
self.getSibling("LabelImageId").props.text = "Database image ID:\n%s" % str(imageId)
#get the image file data back from the put
putReturn = system.net.httpPut(url="http://ignition.vrl.com.au:8088/system/webdev/sw-leviathanCoasterInspection/image",contentType='image/jpg',headerValues={'imageId':imageId,'Accept-Ranges':'bytes'},putData=filedata)
#print the output status
self.getSibling("LabelError").props.text = putReturn
This is the HTTP doPut action:
def doPut(request, session):
#get the incoming parameters putData
imageId = request["headers"]["imageId"]
filedata = request["data"]
try:
#Update the image in the database
query = "UPDATE [dbo].[images] SET image = ? WHERE id = ?"
args = [filedata, imageId]
system.db.runPrepUpdate(query, args, "SEQIGN01_sw_leviathanCoasterInspection")
except Exception as e:
return {'response': "doPost exception error: " + str(e)}
#Check the filedata in logger (will remove later)
logger = system.util.getLogger("doPutLogger")
logger.infof(str(filedata[:100]))
#Check the headers in response (will remove later)
return {'response':request["headers"]}
For some reason (?) the VARBINARY(MAX) data on the DB looks like this: 0x2F396A2F344141555...
I can see in the gateway logs that the request["data"] is actually a byte array:
array('b', [47, 57, 106, 47, 52, 81, 68...
so the data is getting to the doPut as the raw bytes, but it's not getting to the DB as raw byes?
This is what I've tried to resolve the issue:
- Changed the MIME type in the HTTP header to 'application/octet-stream'
- Cast the request["data"] in the doPut to bytes(request["data"])
Any help with this would be appreciated! Thanks!