render Json in Grails format - json

I 'm doing something like this:
def prods = Product.executeQuery("select category.id,category.name, avg(competition1Price), avg(competition2Price), avg(onlineCompetitionPrice) from Product group by category.id")
def output = [[:]]
prods.each { result ->
def prod = ['category_id':result[0],'category_name':result[1],'Competition1Price':result[2],'competition2Price':result[3],'onlineCompetitionPrice':result[4]]
output << prod
}
render output as JSON
the output I'm getting is something like:
[{},{"category_id":1,"category_name":"Colchones y","Competition1Price":1657.4784,"competition2Price":2071.5,"onlineCompetitionPrice":1242.5}]
What I want is:
something like this..
{collection:[{"category_id":"1","category_name":"Colchones y",so on...]}
can someone please help..
How to manipulate the format of json data..

If that's the format you want, you'll need to do:
def prods = Product.executeQuery("select category.id,category.name, avg(competition1Price), avg(competition2Price), avg(onlineCompetitionPrice) from Product group by category.id")
def output = [collection:[]]
prods.each { result ->
def prod = ['category_id':result[0],'category_name':result[1],'Competition1Price':result[2],'competition2Price':result[3],'onlineCompetitionPrice':result[4]]
output.collection << prod
}
render output as JSON
Or (arguably neater):
def prods = Product.executeQuery("select category.id,category.name, avg(competition1Price), avg(competition2Price), avg(onlineCompetitionPrice) from Product group by category.id")
def prodlist = prods.collect { result ->
[ 'category_id': result[0],
'category_name': result[1],
'Competition1Price':result[2],
'competition2Price':result[3],
'onlineCompetitionPrice':result[4] ]
}
render [ collection: prodlist ] as JSON

Related

How to convert simple JSON to DynamoDB JSON?

I have a simple JSON and want to convert it to DynamoDB JSON. Is there any easy way to do that?
If you mean JsonString to Dynamodb Map, you can use boto3.
Here is the example.
import boto3
import json
json_string = '{"key1": 1, "key2": "value"}'
json_obj = json.loads(json_string)
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('test-table')
table.put_item(Item={'pk': 'pk-value', 'map': json_obj})
If you just want to update the while Map attribute, you can use just JSON format the same as put_item.
json_string = '{"key1": 2, "key2": "value2"}'
json_obj = json.loads(json_string2)
rsp = table.update_item(
Key={'pk': 'pk-value'},
AttributeUpdates={'map': {'Value': json_obj2, 'Action': 'PUT'}}
)
However, If you want to update only specific nested attribute, you need to use UpdateExpression. For example, the below is code to update only key1 attribute to 'value3'.
nested_json_string = '{"nested": "key3"}'
nested_json_obj = json.loads(nested_json_string)
rsp = table.update_item(
Key={'pk': 'pk-value'},
UpdateExpression='SET #map.#key1 = :val3',
ExpressionAttributeNames={'#map': 'map', '#key1': 'key1'},
ExpressionAttributeValues={':val3': nested_json_obj}
)
I know this is an old question, but I came across it and the accepted answer didn't help me (it seems to suggest that you can feed boto3 with plain JSON, but it didn't work for me) and the library mentioned in the comments didn't help me either.
What did work for me was using the serializer/deserializer from boto3.dynamodb.types, basically as suggested by this answer on a very similar topic.
from boto3.dynamodb.types import TypeSerializer, TypeDeserializer
import json
serializer = TypeSerializer()
deserializer = TypeDeserializer()
# for building a DynamoDB JSON from a Python object
def serialize(item):
serialized_item = serializer.serialize(vars(item) if hasattr(item, '__dict__') else item)
return item if 'M' not in serialized_item else serialized_item['M']
# for building a plain JSON from a DynamoDB JSON
def deserialize(dynamodb_json_string):
return deserializer.deserialize({'M': dynamodb_json_string})
class MyItem:
def __init__(self, some_string_value=None, some_numeric_value=None):
self.my_key = some_string_value
self.my_other_key = some_numeric_value
def __str__(self):
return json.dumps(self, default=lambda x: x.__dict__)
if __name__ == '__main__':
my_classy_item = MyItem("my_string_value", 5)
my_string_item = json.loads('{"my_key": "my_string_value", "my_other_key" : 5}')
print(serialize(my_classy_item))
print(serialize(my_string_item))

add data to my Json in django

This is how my JSON data looks like
{"id": 50, "first_digit": "2", "second_digit": "1", "calculate": "Addition"}
I want to add extra data "result":"3" to my JSON
this is my view
def calc(request):
if request.method == 'POST':
first_number = request.POST['first number']
second_number = request.POST['second number']
operation = request.POST['operation']
result = do_calc(operation, first_number, second_number)
# how to pass the result to my tempelate
value = Calculation.objects.create(
first_digit=first_number,
second_digit=second_number,
calculate=operation
)
data = model_to_dict(value)
return JsonResponse(data)
Can anyone help me with it
Presumably the output of model_to_dict() is a dict. So you can simply add your value to that dict:
data = model_to_dict(value)
data['result'] = result
return JsonResponse(data)

Parsing the response Json string using groovy

4 for checking the status of the process using httpbuilder and getting the below response.
{"result":[{"id":"167687","dapadmin":"false","status":"in progress","lastupdated":"2017-04-21 14:34:30.0","started":"2017-04-21 14:34:28.0","user":"sys","log":"Running a Stop action\n\nRunning command \n"}]}
Am unable to parse this response using jsonSlurper.parseText() giving error
When I use `
def json = JsonOutput.toJson(statusresponse)
println JsonOutput.prettyPrint(json)
I could see it is printed as json object
{
"result": [
{
"id": "167687",
"dapadmin": "false",
"status": "in progress",
"lastupdated": "2017-04-21 14:34:30.0",
"started": "2017-04-21 14:34:28.0",
"user": "dapsystem",
"log": "Running a Stop action\n\nRunning command \n"
}
]
}
When i check the getClass() , it prints as java.lang.String.
I need to get the lastupdated and status , id values from this response. Please help me to find a solution for this.
Many thanks
Hi Yanpei.
Thanks for the response.
I am using the below code as suggested by you.
def statusresponse = http.putText(baseurl,path,query,headerMap, Method.GET)
println("The status response value is" )
statusresponse.each{ k, v ->
println "${k}:${v}"
}
def json = JsonOutput.toJson(statusresponse)
println "JSON Object List : " + json
println "------------------"
println JsonOutput.prettyPrint(json)
println "The result class is "+json.getClass()
println "The result status is "+(json instanceof Map)
//def entry = slurper.parseText(json)
def slurper = new groovy.json.JsonSlurper()
def entry = slurper.parseText(statusresponse)
def lastupdated = entry.result.lastupdated
checkStatus = entry.result.status
def id = entry.result.id
Am getting the below error
The result class is class java.lang.String
Caught: groovy.lang.MissingMethodException: No signature of method: groovy.json.JsonSlurper.parseText() is applicable for argument types: (java.util.HashMap) values: [[result:[[id:170089, dapadmin:false, status:in progress, ...]]]]
Possible solutions: parseText(java.lang.String), parse(java.io.Reader)
groovy.lang.MissingMethodException: No signature of method: groovy.json.JsonSlurper.parseText() is applicable for argument types: (java.util.HashMap) values: [[result:[[id:170089, dapadmin:false, status:in progress, ...]]]]
Possible solutions: parseText(java.lang.String), parse(java.io.Reader)
at dap.Main.main(Main.groovy:171)
It works if i use the code as below
def json = JsonOutput.toJson(statusresponse)
def entry = slurper.parseText(json)
Am getting the results as below
The status of the action is :[in progress]
Last updated [2017-04-23 17:08:02.0]
the id is[170088]
First of all, am not sure why the code suggested is throwing this error
Secondly, why i am getting the results for the working solution, within the brackets?
def slurper = new groovy.json.JsonSlurper()
def entry = slurper.parseText('{"result":[{"id":"167687","dapadmin":"false","status":"in progress","lastupdated":"2017-04-21 14:34:30.0","started":"2017-04-21 14:34:28.0","user":"sys","log":"Running a Stop action\n\nRunning command \n"}]}')
def lastupdated = entry.result.lastupdated
def status = entry.result.status
def id = entry.result.id
Should work. Can't see your error so I can't give better info.

Serialize SQLAlchemy output to a JSON including column names

I've decided to migrate my Django project to work with SqlAlchemy instead of Django ORM and I'm trying to serialize my SqlAlchemy output to a JSON which contains column names.
In Django I had the following code:
logs = Log.objects.values('log_timestamp', 'message', 'exception', 'level__level', 'job_info__job_name', 'machine', 'user', 'job_report__id').filter(job_info__app_id = app_id).order_by('-time_added')[:1]
logs = json.dumps(list(logs), default=views_utils.default_json_serializer)
print(logs)
and here an output example (contains column names):
[{"user": "user", "level__level": "INFO", "message": "this is a message", "log_timestamp": null, "job_info__job_name": "MongoDB_Maintenance", "exception": "exception details", "machine": "machine", "job_report__id": 65}]
Here is my SqlAlchemy code:
res = session.query(func.DATETIME(LogObj.time_added), LogObj.message, LogObj.exception, LogLevelObj.level, LogObj.machine, LogObj.user).\
join(PeriodicJobInfoObj, LogLevelObj, LogObj,aliased=True).\
filter(PeriodicJobInfoObj.app_id == app_id).\
order_by(desc(LogObj.time_added))[:1]
res = json.dumps(res, default=views_utils.default_json_serializer)
print(res)
The output does not contain column names:
[["2015-09-28 15:36:33", "this is a message", "exception details", "CRITICAL", "machine", "user"]]
default_json_serializer code:
def default_json_serializer(obj):
"""Default JSON serializer."""
import calendar, datetime
if isinstance(obj, datetime.datetime):
if obj.utcoffset() is not None:
obj = obj - obj.utcoffset()
millis = int(
calendar.timegm(obj.timetuple()) * 1000 +
obj.microsecond / 1000
)
return millis
How can I achieve similar output like Django does?
(working with Python 3.4.2)
I have managed to do it this way:
def alchemyencoder(obj):
if isinstance(obj, datetime.date):
return obj.isoformat()
elif isinstance(obj, decimal.Decimal):
return float(obj)
I use the above encoder when retrieving records in following way:
row = conn.execute(Model.__table__.select())
d = json.dumps([dict(r) for r in row], default=alchemyencoder)
d = json.JSONDecoder().decode(d)
print(d)

Django return custom json and add values that need to be deal with

I get a json result, and the images part is not match with the id
like:
{
"id": 11
"title":"AAA"
"createday":"2015-01-01"
"images": [
"B_123.jpg"
],
},
{
"id": 12
"title":"BBB"
"createday":"2015-01-01"
"images": [
"A_123.jpg"
],
},
But actually,id=11 should match the image A_123.jpg ,and id=12 should match the image B_123.jpg
Because the images need to do something in function,so they can't match very well.
How can I let it match with right order?
Here is my code:
views.py
item_list = CombineQueryset(queryset1, queryset2)
return Response(item_list.jsonlize(request))
serializes.py
class CombineQueryset(serializers.ModelSerializer):
def __init__(self, query1, query2, *args, **kwargs):
def get_images(dictionary, obj):
images = []
for image in obj.image_set.all():
images.append(image.path)
dictionary["images"] = images
return dictionary
query_list1 = query1.values(
'title',
'createday',
'id',
)
.....
query_list1 = map(get_images, query_list1, query1)
self.query_list = query_list1 + query_list2
I presume it must be due to something in code not shown, such as different ordering of query_list1 vs query1 or that id=12 is in query2 and the code for query_list2 is not an exact cut and paste of the code for query_list1.
try this instead:
class CombineQueryset(serializers.ModelSerializer):
def __init__(self, query1, query2, *args, **kwargs):
def querylist(queryset):
return [
{
'title': obj.title,
'createday': obj.createday,
'id': obj.id,
'images': obj.image_set.values_list('path', flat=True),
}
for obj in queryset
]
self.query_list = querylist(query1) + querylist(query2)