Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Key Value Pair output
#1
Hi,

My api currently has an output of [1, "Apple"], [2, "Banana"], [3, "Orange"] and I've been told it should be a key value pair. My Return code is

return {
'statusCode': 200,
'headers': {'Content-Type': 'application/json'},
"body": json.dumps(rows)
}
What do I need to do to fix this?

Thanks in advance

Todd
Reply
#2
It's fair to guess that rows is returned from query to database, so it is list/tuple of tuples. You need to convert it to dict, before pass to json.dumps()

import json
rows = [(1, "Apple"), (2, "Banana"), (3, "Orange")]
print(json.dumps(rows))
print(json.dumps(dict(rows)))
Output:
[[1, "Apple"], [2, "Banana"], [3, "Orange"]] {"1": "Apple", "2": "Banana", "3": "Orange"} >>>
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#3
(May-02-2019, 06:06 AM)buran Wrote: It's fair to guess that rows is returned from query to database, so it is list/tuple of tuples. You need to convert it to dict, before pass to json.dumps()

import json
rows = [(1, "Apple"), (2, "Banana"), (3, "Orange")]
print(json.dumps(rows))
print(json.dumps(dict(rows)))
Output:
[[1, "Apple"], [2, "Banana"], [3, "Orange"]] {"1": "Apple", "2": "Banana", "3": "Orange"} >>>

Thanks Buran,

You are correct in that this is results from a query. The code also executes inside a AWS Lambda function.

Ive modified my code to

return {
        'statusCode': 200,
        'headers': {'Access-Control-Allow-Origin': '*',
        'Content-Type': 'application/json'},
        "body": json.dumps(dict((rows))
    }
But am getting syntax error

Im told that output should be

{
"body": [{
"Id”: "1”,
"Fruit”: "Apple”
},{
"Id”: "2”,
"Fruit”: "Banana”
}]
}
Reply
#4
the error is because you have extra opening bracket between dict and row.
if you need to get different json as body - construct the list of dicts

import json
rows = [(1, "Apple"), (2, "Banana"), (3, "Orange")]
json_rows = [dict(zip(('Id', 'Fruit'), (str(key), value))) for key, value in rows]
print(json.dumps(json_rows))
Output:
[{"Id": "1", "Fruit": "Apple"}, {"Id": "2", "Fruit": "Banana"}, {"Id": "3", "Fruit": "Orange"}] >>>
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#5
Thanks buran,

Im now getting error

"errorMessage": "dictionary update sequence element #0 has length 7; 2 is required",
"errorType": "ValueError",

Sorry I don't understand what you mean "construct the list of dicts"

Cheers

Todd
Reply
#6
(May-02-2019, 07:00 AM)UtiliseIT Wrote: Im now getting error

"errorMessage": "dictionary update sequence element #0 has length 7; 2 is required",
"errorType": "ValueError",


I don't understand that error. Post your full code as well as full traceback you get

I have added example to my previous answer already
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#7
OK here is my full code

Before worrying about the error message. 1st question would be if i have the correct format for line 23

Then next question would be if I have it in the right place.

I am using the Official Python Connector for MySQL.

Thanks in advance.

import os
import sys
import logging
sys.path.insert(0, '/opt')
import json
import mysql.connector


logger = logging.getLogger()
logger.setLevel(logging.INFO)


logger.info("SUCCESS: Connection to DB instance succeeded")

def lambda_handler(event, context):
    cnx = mysql.connector.connect(user=os.environ['user'], database=os.environ['database'], host=os.environ['host'], password=os.environ['password'])
    cursor = cnx.cursor()
        
    query = ("SELECT distinctrow UPC, ItemFriendlyNames, ItemName, Brand, Model, Retailer, ItemID FROM my.view order by UPC, Model, Retailer")
        
    cursor.execute(query)
    rows = cursor.fetchall()
    json_rows = [dict(zip(('UPC', 'ItemFriendlyNames', 'ItemName', 'Brand', 'Model', 'Retailer', 'ItemID'), (str(key), value, value, value, value, value, value))) for key, value in rows]
    
    cursor.close()
    cnx.close()

    return {
        'statusCode': 200,
        'headers': {'Access-Control-Allow-Origin': '*',
        'Content-Type': 'application/json'},
         "body": json.dumps(rows)
    }
    
    
    
    
Reply
#8
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
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#9
Thank you Buran,

Can you elaborate more on your comment regarding cursor.fetchall

Appreciate it
Reply
#10
from my last alternative
you can replace

rows = cursor.fetchall()
json_rows = [dict(zip(('UPC', 'ItemFriendlyNames', 'ItemName', 'Brand', 'Model', 'Retailer', 'ItemID'), (str(key), *values))) for key, *values in rows]
with just

json_rows = [dict(zip(('UPC', 'ItemFriendlyNames', 'ItemName', 'Brand', 'Model', 'Retailer', 'ItemID'), (str(key), *values))) for key, *values in cursor]
here from the docs:


Quote:After executing the query, the MySQL server is ready to send the data. The result set could be zero rows, one row, or 100 million rows. Depending on the expected volume, you can use different techniques to process this result set. In this example, we use the cursor object as an iterator. The first column in the row is stored in the variable first_name, the second in last_name, and the third in hire_date.


i.e. you can use cursor as iterator instead of using cursor.fetchone(), cursor.fetchall(), cursor.fetchmany()
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Getting the maximum value:key pair from a dictionary sean1 2 1,534 Jan-17-2022, 01:04 PM
Last Post: DeaD_EyE
  How to extract specific key value pair from string? aditi06 0 2,643 Apr-15-2021, 06:26 PM
Last Post: aditi06
  Auto re-pair / re-sync Controller via Script? User3000 2 2,468 Nov-30-2020, 11:42 AM
Last Post: User3000
  team pair issue jk91 29 8,808 Mar-03-2020, 06:15 PM
Last Post: jefsummers
  Search a List of Dictionaries by Key-Value Pair; Return Dictionary/ies Containing KV dn237 19 7,087 May-29-2019, 02:27 AM
Last Post: heiner55
  Parsing Text file having repeated value key pair using python manussnair 3 3,403 Aug-04-2018, 11:48 PM
Last Post: micseydel

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020