Each row in your actual query has 7 elements, while in your sample data had just 2. In the sample it was easy to asign each of these elements to different [meaningful] variable name. In the real query you can do the same - unpack each row into 7 different variables. Or you can do something different.
Let's focus just on line 23 and how you can replace it (any of the following would do):
json_rows = [dict(zip(('UPC', 'ItemFriendlyNames', 'ItemName', 'Brand', 'Model', 'Retailer', 'ItemID'),
(str(upc), item_friendly_name, item_name, brand, model, retailer, item_id)))
for upc, item_friendly_name, item_name, brand, model, retailer, item_id in rows]
json_rows = [dict(zip(('UPC', 'ItemFriendlyNames', 'ItemName', 'Brand', 'Model', 'Retailer', 'ItemID'), map(str, row))) for row in rows]
json_rows = [dict(zip(('UPC', 'ItemFriendlyNames', 'ItemName', 'Brand', 'Model', 'Retailer', 'ItemID'), (str(key), *values))) for key, *values in rows]
there are also other ways to do that... E.g. using map will cast to str all elements in the row. if there are some values that are not str and you need to keep them then you need to use something different
some more thoughts.
1. Instead of using
cursor.fetchall()
you can iterate directly over the cursor
2. instead of converting upc to str in the list comprehension (the line 23) you can cast it to string in the sql statement directly
"SELECT distinctrow CAST(UPC AS CHAR), ItemFriendlyNames, ItemName, Brand, Model, Retailer, ItemID FROM my.view order by UPC, Model, Retailer"
Also note that on line 32 you need to dump json_rows, not just rows