I've been experimenting with python for a while and just ran into an issue I can't find an answer to. Just started building a small 'banking' console app and it's "database" is in JSON file. Now I added a command called 'transfer' which should transfer 'funds' from one user_id to another.
JSON file looks like this:
{
"users": [
{
"user_id": "u111111111",
"pin": "2222",
"balance": "50800"
},
{
"user_id": "u123456789",
"pin": "1234",
"balance": "0"
}
]
}
Last thing I tried was something like this and got completely stuck.
user_database = 'accounts.json'
ujf = json.loads(open(user_database, 'r+').read())
for element in ujf['users']:
if (element['user_id'] == str(user_id_one)):
element['balance'] = str(user_one_new_balance)
else:
pass
How do I update the 'balance' value for user_id u111111111 and for user_id u123456789 and save the file, without creating a new file?
First import JSON module:
import json
Then load the JSON file as dictionary:
d = json.load(r'PATH')
Then inside the loop you can assign user['balance'] to whatever you like, e.g. 8 here:
for user in d['users']:
if user['user_id'] in ['u111111111','u123456789']:
user['balance'] = 8
Then dump back:
json.dump(d,(open(r'PATH','w')))
Related
I want to store key-value JSON data in aws DynamoDB where key is a date string in YYYY-mm-dd format and value is entries which is a python dictionary. When I used boto3 client to save data there, it saved it as a data type object, which I don't want. My purpose is simple: Store JSON data against a key which is a date, so that later I will query the data by giving that date. I am struggling with this issue because I did not find any relevant link which says how to store JSON data and retrieve it without any conversion.
I need help to solve it in Python.
What I am doing now:
item = {
"entries": [
{
"path": [
{
"name": "test1",
"count": 1
},
{
"name": "test2",
"count": 2
}
],
"repo": "test3"
}
],
"date": "2022-10-11"
}
dynamodb_client = boto3.resource('dynamodb')
table = self.dynamodb_client.Table(table_name)
response = table.put_item(Item = item)
What actually saved:
[{"M":{"path":{"L":[{"M":{"name":{"S":"test1"},"count":{"N":"1"}}},{"M":{"name":{"S":"test2"},"count":{"N":"2"}}}]},"repo":{"S":"test3"}}}]
But I want to save exactly the same JSON data as it is, without any conversion at all.
When I retrieve it programmatically, you see the difference of single quote, count value change.
response = table.get_item(
Key={
"date": "2022-10-12"
}
)
Output
{'Item': {'entries': [{'path': [{'name': 'test1', 'count': Decimal('1')}, {'name': 'test2', 'count': Decimal('2')}], 'repo': 'test3'}], 'date': '2022-10-12} }
Sample picture:
Why not store it as a single attribute of type string? Then you’ll get out exactly what you put in, byte for byte.
When you store this in DynamoDB you get exactly what you want/have provided. Key is your date and you have a list of entries.
If you need it to store in a different format you need to provide the JSON which correlates with what you need. It's important to note that DynamoDB is a key-value store not a document store. You should also look up the differences in these.
I figured out how to solve this issue. I have two column name date and entries in my dynamo db (also visible in screenshot in ques).
I convert entries values from list to string then saved it in db. At the time of retrival, I do the same, create proper json response and return it.
I am also sharing sample code below so that anybody else dealing with the same situation can have atleast one option.
# While storing:
entries_string = json.dumps([
{
"path": [
{
"name": "test1",
"count": 1
},
{
"name": "test2",
"count": 2
}
],
"repo": "test3"
}
])
item = {
"entries": entries_string,
"date": "2022-10-12"
}
dynamodb_client = boto3.resource('dynamodb')
table = dynamodb_client.Table(<TABLE-NAME>)
-------------------------
# While fetching:
response = table.get_item(
Key={
"date": "2022-10-12"
}
)['Item']
entries_string=response['entries']
entries_dic = json.loads(entries_string)
response['entries'] = entries_dic
print(json.dumps(response))
I had .xlsx file, and I converted it to JSON. I am using python to get the data from this json file. I am able for example to search for Build# and then I get the corresponding level, but when I search for values in, for example, "14H0232" or "14H4812" it throws a KeyError.
'''
import json
f = open('try.json')
data = json.load(f)
input= input('Enter the value: ')
for i in data['F6']:
if i['14H0232'] == input:
print(i['LEVEL'])
f.close()
'''
A Snippet of the json file.
'''
{
"F6": [
{
"LEVEL": "2.0.6.0",
"ID": "dataID",
"Build#": "9",
"prod/dev": "prod ",
"14H4812": "data1\r\ndata2",
"14H4826": "data",
"14H4813": "data1\r\ndata2"
}
],
"F5": [
{
"LEVEL": "2.0.5.1",
"ID": "dataID",
"Build#": "18",
"prod/dev": "prod",
"14H0232": "data1: data1\r\ndata2: data2\r\ndata3: data3",
"14H12321": "data1\r\ndata2"
}
],
"F4": [
{
"LEVEL": "2.0.4.1",
"ID": "dataID",
"Build#": "18",
"prod/dev": "prod",
"14H0232": "data1: data1\r\ndata2: data2\r\ndata3: data3",
"14H12321": "data1\r\ndata2"
}
]
}
'''
The problem is in your loop. When you are trying to access the value for "14H0232" it just doesnt exist in your json file. The case for 'Build#' is different I assume, as the key is always there. The example you shared is also not showing that F6 has a key with that id you specified.
So to avoid this kind of errors you can put your 'if' statement in a try block and catch the error.
try:
if i['14H0232'] == input:
print(i['LEVEL'])
except KeyError:
print("The key is not found but the code continues to execute")
I've got a json file that I've pulled from a web service and am trying to parse it. I see that this question has been asked a whole bunch, and I've read whatever I could find, but the json data in each example appears to be very simplistic in nature. Likewise, the json example data in the python docs is very simple and does not reflect what I'm trying to work with. Here is what the json looks like:
{"RecordResponse": {
"Id": blah
"Status": {
"state": "complete",
"datetime": "2016-01-01 01:00"
},
"Results": {
"resultNumber": "500",
"Summary": [
{
"Type": "blah",
"Size": "10000000000",
"OtherStuff": {
"valueOne": "first",
"valueTwo": "second"
},
"fieldIWant": "value i want is here"
The code block in question is:
jsonFile = r'C:\Temp\results.json'
with open(jsonFile, 'w') as dataFile:
json_obj = json.load(dataFile)
for i in json_obj["Summary"]:
print(i["fieldIWant"])
Not only am I not getting into the field I want, but I'm also getting a key error on trying to suss out "Summary".
I don't know how the indices work within the array; once I even get into the "Summary" field, do I have to issue an index manually to return the value from the field I need?
The example you posted is not valid JSON (no commas after object fields), so it's hard to dig in much. If it's straight from the web service, something's messed up. If you did fix it with proper commas, the "Summary" key is within the "Results" object, so you'd need to change your loop to
with open(jsonFile, 'w') as dataFile:
json_obj = json.load(dataFile)
for i in json_obj["Results"]["Summary"]:
print(i["fieldIWant"])
If you don't know the structure at all, you could look through the resulting object recursively:
def findfieldsiwant(obj, keyname="Summary", fieldname="fieldIWant"):
try:
for key,val in obj.items():
if key == keyname:
return [ d[fieldname] for d in val ]
else:
sub = findfieldsiwant(val)
if sub:
return sub
except AttributeError: #obj is not a dict
pass
#keyname not found
return None
I have a json object which I would like to filter for misspelled key name. So for the example below, I would like to have a json object without the misspelled test_name key. What is the easiest way to do this?
json_data = """{
"my_test": [{
"group_name": "group-A",
"results": [{
"test_name": "test1",
"time": "8.556",
"status": "pass"
}, {
"test_name": "test2",
"time": "45.909",
"status": "pass"
}, {
"test_nameZASSD": "test3",
"time": "9.383",
"status": "fail"
}]
}]
}"""
This is an online test, and looks like i'm not allowed to use jsonSchema.
So far my code looks like this:
if 'test_suites' in data:
for suites in data["test_suites"]:
if 'results' in suites and 'suite_name' in suites:
for result in suites["results"]:
if 'test_name' not in result or 'time' not in result or 'status' not in result:
result.clear()
else:
....
else:
print("Check 'suite_name' and/or 'results'")
else:
print("Check 'test_suites'")
It kind of works, but result.clear() leaves a empty {}, which get annoying later. What can I do here?
It looks like your data have a consistent schema. So I would try using json schema to solve your problem. With that you can set up a schema and only allow objects with certain key names.
If you just want to check if a certain key is in the dictionary and make sure that you only get the ones that are according to spec you could do something like this:
passed = []
for item in result:
if 'test_name' in item.keys():
passed.append(item)
But if you have a lot of different keys you need to check for it will become unwieldy. So for bigger projects I would say that json schema is the way to go.
I have successfully written a script to pull information from a json file and parse this in a way in which I will I can use but I at the moment I have to manually print each string. I would like to loop this if possible but stuck on where to start?
Python
from __future__ import print_function
import json
import sys
from pprint import pprint
with open('screen.json') as data_file:
data = json.load(data_file)
#json_file.close()
# Print all json data
#pprint(data)
#screen_list = data['screen']
print ("Screens availble",len (data['screen']))
#pprint(data["screen"][1]["id"])
#pprint(data["screen"][1]["user"])
#pprint(data["screen"][1]["password"])
#pprint(data["screen"][1]["code"])
#How to loop this
print ("https://",data["screen"][0]["server"],"/test/test.php?=",data["screen"][0]["code"],sep='')
print ("https://",data["screen"][1]["server"],"/test/test.php?=",data["screen"][1]["code"],sep='')
print ("https://",data["screen"][2]["server"],"/test/test.php?=",data["screen"][2]["code"],sep='')
JSON
{
"screen": [
{
"id": "1",
"user": "user1#example.com",
"password": "letmein",
"code": "123456",
"server": "example.com"
},
{
"id": "2",
"user": "user2#example.com",
"password": "letmein",
"code": "123455",
"server": "example.com"
},
{
"id": "3",
"user": "user3#example.com",
"password": "letmein",
"code": "223456",
"server": "example.com"
}
]
}
You've already pulled data['screen'] out into a variable named screen_list. That variable is a list, so you can use it the same as any other list—call len on it, index it, or loop over it. So:
screen_list = data['screen']
print("Screens availble", len(screen_list))
for screen in screen_list:
pprint(screen['id'])
pprint(screen['user'])
pprint(screen['password'])
pprint(screen['code'])
And, down below, just loop again:
for screen in screen_list:
print("https://", screen["server"], "/test/test.php?=", screen["code"], sep='')
(I'm assuming you want to print out all the screens' info, then print out all the URLs. If you want to print each URL at the same time you print the info, just merge them into one loop.)
As a side note, this is a good time to learn about string formatting. If you want to use those URLs to, e.g., pass them to urllib2 or requests, you can't just print them out, you have to make them into strings. Even if you do just want to print them out, formatting is usually easier to read and harder to get wrong. So:
print("https://{}/test/test.php?={}".format(screen["server"], screen["code"]))
… or …
print("https://{server}/test/test.php?={code}".format(**screen))
You can iterate over the list of dicts:
for d in data["screen"]:
print ("https://",d["server"],"/test/test.php?=",d["code"],sep='')
Out:
https://example.com/test/test.php?=123456
https://example.com/test/test.php?=123455
https://example.com/test/test.php?=223456