I'm new to TinyDB, and new to Python.
I have various usernames stored in a TinyDB database, they also have other information stored (age, email addresses etc), however, I wish to return all the usernames only.
{"_default": {"1": {"Username": "John", "Age": "30"}, "2": {"Username":
"Andrew", "Age":"40", "Email": "example#example.com"}}}
My GUI would have the button "Show all usernames".
I can return information about specific users, and I can get all the information stored in the database (db.all()), however I cannot just seem to get all the usernames from the entire database.
Is there a way to do this?
Or am I looking at this problem the wrong way.
Many thanks!
The database itself is iterable, so perhaps this would be more elegant and would avoid having to open the JSON file directly:
db = TinyDB('database_name.json')
usernames = [r['Username'] for r in db]
Gives:
['John', 'Andrew']
Update: I found a (slightly convoluted) workaround.
It involves reading the file as a JSON file and then looping through the dictionary IDs, stopping the loop upon a key error.
with open("database_name.json", "r") as read_file:
data=json.load(read_file)
try:
current_number = 1
while current_number <=100000000000:
current_number = str(current_number)
print(data['_default'][current_number]['Username'])
current_number = int(current_number)
current_number += 1
except:
KeyError
Related
I'm new to developing and my question(s) involves creating an API endpoint in our route. The api will be used for a POST from a Vuetify UI. Data will come from our MongoDB. We will be getting a .txt file for our shell script but it will have to POST as a JSON. I think these are the steps for converting the text file:
1)create a list for the lines of the .txt
2)add each line to the list
3) join the list elements into a string
4)create a dictionary with the file/file content and convert it to JSON
This is my current code for the steps:
import json
something.txt: an example of the shell script ###
f = open("something.txt")
create a list to put the lines of the file in
file_output = []
add each line of the file to the list
for line in f:
file_output.append(line)
mashes all of the list elements together into one string
fileoutput2 = ''.join(file_output)
print(fileoutput2)
create a dict with file and file content and then convert to JSON
json_object = {"file": fileoutput2}
json_response = json.dumps(json_object)
print(json_response)
{"file": "Hello\n\nSomething\n\nGoodbye"}
I have the following code for my baseline below that I execute on my button press in the UI
#bp_customer.route('/install-setup/<string:customer_id>', methods=['POST'])
def install_setup(customer_id):
cust = Customer()
customer = cust.get_customer(customer_id)
### example of a series of lines with newline character between them.
script_string = "Beginning\nof\nscript\n"
json_object = {"file": script_string}
json_response = json.dumps(json_object)
get the install shell script content
replace the values (somebody has already done this)
attempt to return the below example json_response
return make_response(jsonify(json_response), 200)
my current Vuetify button press code is here: so I just have to ammend it to a POST and the new route once this is established
onClickScript() {
console.log("clicked");
axios
.get("https://sword-gc-eadsusl5rq-uc.a.run.app/install-setup/")
.then((resp) => {
console.log("resp: ", resp.data);
this.scriptData = resp.data;
});
},
I'm having a hard time combining these 2 concepts in the correct way. Any input as to whether I'm on the right path? Insight from anyone who's much more experienced than me?
You're on the right path, but needlessly complicating things a bit. For example, the first bit could be just:
import json
with open("something.txt") as f:
json_response = json.dumps({'file': f.read()})
print(json_response)
And since you're looking to pass everything through jsonify anyway, even this would suffice:
with open("something.txt") as f:
data = {'file': f.read()}
Where you can pass data directly through jsonify. The rest of it isn't sufficiently complete to offer any concrete comments, but the basic idea is OK.
If you have a working whole, you could go to https://codereview.stackexchange.com/ to ask for some reviews, you should limit questions on StackOverflow to actual questions about getting something to work.
Hello there this is my first stackoverflow question please bear with me.
my JSON file looks like this:
{"users":
[
{"name": "John Smith",
"phone_num":"+104484932"
},
{"name": "Linda Ray",
"phone_num": "+194387282"
}
]
}
when given an input the script should look for the name in this list of dictionaries and return the phone number, I have tried many resources, it might also look like a possible copy of this question.
Which it isn't, thanks for your help in advance.
Load the json file into a python dict, then iterate over the users list.
def myfunction(target_name):
with open('file.json') as f:
data = json.load(f)
for user in data['users']:
if user['name'] == target_name:
return user['phone_num']
You can do it in a simple way like
json = {"users":
[
{"name": "John Smith",
"phone_num":"+104484932"
},
{"name": "Linda Ray",
"phone_num": "+194387282"
}
]
}
inp = input('Name: ')
print([i['phone_num'] for i in json['users'] if i['name'] == inp][0])
Tell me if its not working...
We don't have access to your code, so not sure what approach you are taking. Gonna presume that this is simple and barebones.
If the file is json, it will need to be read in and that will require that we import the json library.
import json
The question implies we are getting input directly from the user, so we can use the input() function to gather that data. Here we are providing a prompt that will display on the screen when the script is run.
username = input("Please supply a name: ")
From there, we read in the json file which gets read in as a Python dictionary. Since it is a dictionary (Python dict()), we can drill down into it to get to the data we care about querying on specific keys to see the associated values.
When we open() the file and I am choosing to refer to the opened file as fin. Then we pull out the content that is stored under the users key (that value happens to be a list of people).
with open('filename.json') as fin:
book = json.load(fin)
users = data['users']
Then we parse each user in the users list and check for matches to the username that was input earlier. When it finds a match, it prints the corresponding phone number.
for user in users:
if user['name'] == username:
print(user['phone_num'])
The script in total will look something like this:
import json
username = input("Please supply a name: ")
with open('filename.json') as fin:
book = json.load(fin)
users = data['users']
for user in users:
if user['name'] == username:
print(user['phone_num'])
I return object from the MongoDB database, using python. I want to see now if the property revokedTokens exists. This is my code:
usersCollection = db["users"]
searchQuery = { "username": username }
user = usersCollection.find_one(searchQuery)
print("user is:")
print(user)
if hasattr(user, "revokedTokens"):
print("appending")
user["revokedTokens"].append("another")
#user["revokedTokens"].append(jwt)
else:
print("adding first element")
user["revokedTokens"] = ["first"]
#user["revokedTokens"] = [jwt]
but I always end up in the wrong print ( print("adding first element") ) , so I don't know how to check this. Thanks everyone for correcting me, I am a python newbie!
find_one returns a dict so what you need to ask is if "revokedTokens" in user or if user.get('revokedTokens') is not None
Generally, it is probably better practice to use the $exists MongoDB operator.
To make your code work (if you don't want to use the MongoDB query way), you should replace:
if hasattr(user, "revokedTokens"):
with
if "revokedTokens" in user:
This is because the query returns a dict object, and not a structured class
I have the DynamoDB table that is filled from different services/sources. The table has next schema:
{
"Id": 14782,
"ExtId": 1478240974, //pay attention it is Number
"Name": "name1"
}
Sometimes, after services started to work I had found that one service sends data in incorrect format. It looks like:
{
"Id": 14782,
"ExtId": "1478240974", //pay attention it is String
"Name": "name1"
}
DynamoDB is NoSQL database so, now I have millions mixed records that are difficult to query or scan. I understand that my main fault was missed validation.
Now I have to go throw all records and if it is inappropriate type - remove it and add with same data but with the correct format. Is it possible to do in another gracefully way?
So it was pretty easy. It is possible to do with attribute_type method.
First of all, I added imports:
from boto3.dynamodb.conditions import Attr
import boto3
And my code:
attr = Attr('ExtId').attribute_type('S')
response = table.scan(FilterExpression = attr)
items = response['Items']
while 'LastEvaluatedKey' in response:
response = table.scan(FilterExpression = attr, ExclusiveStartKey = response['LastEvaluatedKey'])
items.extend(response['Items'])
It is possible to find more condition customization in the next article - DynamoDB Customization Reference
I'm brand new to Python coming over from a javascript/nodeJS upbringing. I have a python dictionary with a nested list that I'm having lots of trouble accessing. I need to pull out the nested list so I can check for unique e-mails. Here is what my GET request pulls back:
{"data": [{"login_date": "2014-04-17T19:14:29+08:00", "email": "walter.elwyn#yahoo.com"}, {"login_date": "2014-04-22T09:31:56+04:00", "email": "helyn67#cruickshankmckenzie.com"}]
The actual data dictionary that gets returned is much longer but you get the point... so I have two questions:
how do I access a specific point by e-mail in the content dictionary
how do I loop over the dictionary for unique emails?
Here is my code:
from flask import Flask
import requests
import urllib2
app = Flask(__name__)
#app.route('/')
def hello_world():
content = urllib2.urlopen('https://9g9xhayrh5.execute-api.us-west-2.amazonaws.com/test/data').read()
print content
return 'check console'
if __name__ == '__main__':
app.run()
If you have a structure like this:
>>> response = {"data": [{"login_date": "2014-04-17T19:14:29+08:00", "email": "walter.elwyn#yahoo.com"}, {"login_date": "2014-04-22T09:31:56+04:00", "email": "helyn67#cruickshankmckenzie.com"}]}
Then what you have is a dict with key data
>>> response['data']
[{'login_date': '2014-04-17T19:14:29+08:00', 'email': 'walter.elwyn#yahoo.com'}, {'login_date': '2014-04-22T09:31:56+04:00', 'email': 'helyn67#cruickshankmckenzie.com'}]
You can get a list of emails with a list comprehension:
>>> [user['email'] for user in response['data']]
['walter.elwyn#yahoo.com', 'helyn67#cruickshankmckenzie.com']
How do I loop over the dictionary for unique emails?
To make that list unique, you can use a set comprehension:
>>> {user['email'] for user in response['data']}
set(['helyn67#cruickshankmckenzie.com', 'walter.elwyn#yahoo.com'])
How do I access a specific point by e-mail in the content dictionary
If you want to filter for a given email, you can use filter()
>>> filter(lambda user: user['email'] == 'walter.elwyn#yahoo.com', response['data'])
[{'login_date': '2014-04-17T19:14:29+08:00', 'email': 'walter.elwyn#yahoo.com'}]
If I do content['data] in my case, I get an internal server error
That's because to do content['data'], content needs to be a dict-like object. Let's use requests lib to do what you want:
>>> import requests
>>> content = requests.get('https://9g9xhayrh5.execute-api.us-west-2.amazonaws.com/test/data')
>>> response = content.json() # reads the data as JSON, into a dict-like object
>>> response.keys()
[u'data']
Now you can use response['data']