Search for a dynamic field in a mongodb collection - python

If I were to search for a particular field in a mongodb collection my command would look something like this :
db.collection.find({ name : "John"})
If I want to make the field name dynamic, what would the command be?
Example:
db.collection.find({ <Dyanmic field variable> : <Value>})
Or is there an alternative to achieve this function?

Just use the variable in place of the dictionary key:
name = 'field_name'
db.collection.find({name : "John"})

Problem happens when you try without knowing data type. So in order to handle this , i used the following:
def multi_row_single_field_update(self, crieteriafldnm, crieteriafldtyp, updtfldnm, updtfldval, updtfldtyp):
try:
criteria = raw_input('\nEnter ' + crieteriafldnm + ' to update\n')
if crieteriafldtyp == 'int':
count = self.my_connect.find({str(crieteriafldnm): int(criteria)}).count()
else:
count = self.my_connect.find({str(crieteriafldnm): str(criteria)}).count()
updt_criteria = int(criteria) if updtfldtyp == 'int' else str(criteria)
self.my_connect.update(
{"$atomic": 1},
{str(crieteriafldnm): updt_criteria},
{"$set": {str(updtfldnm): str(updtfldval)}},
upsert=False, multi=True
)

Related

Is there a Ternary Operator in python

I'm trying to do a ternary like operator for python to check if my dictionary value exist then use it or else leave it blank, for example in the code below I want to get the value of creator and assignee, if the value doesn't exist I want it to be '' if theres a way to use ternary operator in python?
Here's my code :
in_progress_response = requests.request("GET", url, headers=headers, auth=auth).json()
issue_list = []
for issue in in_progress_response['issues'] :
# return HttpResponse( json.dumps( issue['fields']['creator']['displayName'] ) )
issue_list.append(
{
"id": issue['id'],
"key": issue['key'],
# DOESN'T WORK
"creator": issue['fields']['creator']['displayName'] ? '',
"is_creator_active": issue['fields']['creator']['active'] ? '',
"assignee": issue['fields']['assignee']['displayName'] ? '',
"is_assignee_active": issue['fields']['assignee']['active'] ? '',
"updated": issue['fields']['updated'],
}
)
return issue_list
Ternary operators in python act as follows:
condition = True
foo = 3.14 if condition else 0
But for your particular use case, you should consider using dict.get(). The first argument specifies what you are trying to access, and the second argument specifies a default return value if the key does not exist in the dictionary.
some_dict = {'a' : 1}
foo = some_dict.get('a', '') # foo is 1
bar = some_dict.get('b', '') # bar is ''
You can use .get(…) [Django-doc] to try to fetch an item from a dictionary and return an optional default value in case the dictionary does not contain the given key, you thus can implement this as:
"creator": issue.get('fields', {}).get('creator', {}).get('displayName', ''),
the same with the other items.
if you want to use something like ternary then
you can say
value = issue['fields']['creator']['displayName'] if issue['fields']['creator'] else ""

How to print a value in Python that is inside a Json in MongoDB object

I have this Json, and I need a value from a rate.
"_id" : ObjectId("5addb57d0043582d48ba898a"),
"success" : true,
"timestamp" : 1524477784,
"base" : "EUR",
"date" : "2018-04-23",
"rates" : {
"AED" : 4.492662,
"AFN" : 85.576329,
"ALL" : 128.39508,
"AMD" : 586.837094,
"ANG" : 2.177608,
"AOA" : 267.092358,
"ARS" : 24.678283,
"AUD" : 1.602032,
"AWG" : 2.177639,
"AZN" : 2.079155,
"BAM" : 1.958775,
"BBD" : 2.446786,
"BDT" : 101.517146,
"BGN" : 1.943843,
"BHD" : 0.460968,
"NOK" : 9.626194,
}
And this is my Python code
import pymongo
uri = "mongodb://127.0.0.1:27017"
client = pymongo.MongoClient(uri)
database = client['db']
collection = database['currency']
collection2 = database['countries']
p = str(input('Insert the country: ')).capitalize()
if p=='Norway':
currency = collection.find_one({'NOK'})
print(currency)
I want to print the value inside de NOK, how can I do it?
Thanks in advance.
I think you can call it by :
currency = collection.find_one({"NOK"})
print(currency['rates']['NOK'])
What you're trying to do is fetch a value in a dictionary which is integrated inside of another dictionary. JSON returns are dictionaries.
I imagine that the collection variable contains the JSON return
One way of fetching this data is by calling the dictionary and telling it what key you want the dictionary to return, as the "NOK" key is in the "rates" key we will be calling the rates key first, then when the dictionary has returned the dictionary that contains the "NOK" key we will then pass the "NOK" key to that returned dictionary, so the code looks like this:
currency = collection["rates"]["NOK"]
Another way of doing this is using the for loop, it is a lot longer but may help you understand.
for key in collection:
if key == "rates":
for keyRates in JSON[key]:
if keyRates == "NOK":
currency = JSON[key][keyRates]
Hope this helps

Jira Python Custom Fields

I am writing a script to create bugs. We have many custom fields and I cannot figure out how to get them to work correctly in the python code. Can someone please help explain? I have read through as many articles as I can find but none of the solutions are working.
One example of my custom field names is customfield_15400 and has a default value of "NO". The error I get with my below code is:
response text = {"errorMessages":[],"errors":{"customfield_15400":"Could not find valid 'id' or 'value' in the Parent Option object."}}
Code:
project_dict = {'Aroid':'SA', 'OS':'SC'}
epic_dict = {'Aroid':'SA-108', 'OS':'SC-3333'}
for index, row in bugs.iterrows():
issue = st_jira.create_issue(project= project_dict[row['OS']], \
summary= "[UO] QA Issue with '%s' on '%s'" % (row['Event Action'], row['Screen Name']), \
issuetype= {'name':'Bug'},\
customfield_15400="No"
)
Try the following :
customfield_15400={ 'value' : 'NO' }
You can also do the following, value_id being the id of the value in your Select Field :
customfield_15400={ 'id' : 'value_id' }
Indeed the value of a SelectField is an object, described by its value and its ID.
Incase anyone else needs the solution. Below works.
project_dict = {'Android':'SA', 'iOS':'SIC'}
epic_dict = {'Android':'SA-18', 'iOS':'SIC-19'}
for index, row in bugs.iterrows():
issue = st_jira.create_issue(
summary= "[UO] QA Issue with '%s' on '%s'" % (row['Event Action'], row['Screen Name']),\
labels = ['UO'],\
assignee={"name":""},\
versions=[{"name":"4.4"}],\
fields={'project' : project_dict[row['OS']], \
'summary': "[UO] QA Issue with '%s' on '%s'" % (row['Event Action'], row['Screen Name']),\
'labels': ['UO'],\
'assignee':{"name":""},\
'versions':[{"name":"4.4"}],\
'issuetype': {'name':'Bug'},\
'customfield_15400': {'value':'Yes'}}
)
issue.update(fields={'customfield_10100': {'value','Two'}})
I have a multiselect list and below error occurs if i try to update
"response text = {"errorMessages":[],"errors":{"Custom_field":"data was not an array"}}"
issue.update(fields={'customfield_10100': {'value','Two'}})
above will throw the error saying data was not an array
"response text = {"errorMessages":[],"errors":{"Custom_field":"data was not an array"}}"
=> you could try like this -:
issue.update(fields={'customfield_10100': [{'value': "Two"}]})

How to Add item to string_set on Dynamodb with Boto3

I have read the official AWS docs and several forums, still I cant find what I am doing wrong while adding item to string_set using Python/Boto3 and Dynamodb. Here is my code:
table.update_item(
Key={
ATT_USER_USERID: event[ATT_USER_USERID]
},
UpdateExpression="add " + key + " :val0" ,
ExpressionAttributeValues = {":val0" : set(["example_item"]) },
)
The error I am getting is:
An error occurred (ValidationException) when calling the UpdateItem operation: An operand in the update expression has an incorrect data type\"
It looks like you figured out a method for yourself, but for others who come here looking for an answer:
Your 'Key' syntax needs a data type (like 'S' or 'N')
You need to use "SS" as the data type in ExpressionAttributeValues, and
You don't need "set" in your ExpressionAttributeValues.
Here's an example I just ran (I had an existing set, test_set, with 4 existing values, and I'm adding a 5th, the string 'five'):
import boto3
db = boto3.client("dynamodb")
db.update_item(TableName=TABLE,
Key={'id':{'S':'test_id'}},
UpdateExpression="ADD test_set :element",
ExpressionAttributeValues={":element":{"SS":['five']}})
So before, the string set looked like ['one','two','three','four'], and after, it looked like ['one','two','three','four','five']
Building off of #joe_stech's answer, you can now do it without having to define the type.
An example is:
import boto3
class StringSetTable:
def __init__(self) -> None:
dynamodb = boto3.resource("dynamodb")
self.dynamodb_table = dynamodb.Table("NAME_OF_TABLE")
def get_str_set(self, key: str) -> typing.Optional[typing.Set[str]]:
response = self.dynamodb_table.get_item(
Key={KEY_NAME: key}, ConsistentRead=True
)
r = response.get("Item")
if r is None:
print("No set stored")
return None
else:
s = r["string_set"]
s.remove("EMPTY_IF_ONLY_THIS")
return s
def add_to_set(self, key: str, str_set: typing.Set[str]) -> None:
new_str_set = str_set.copy()
new_str_set.add("EMPTY_IF_ONLY_THIS")
self.dynamodb_table.update_item(
Key={KEY_NAME: key},
UpdateExpression="ADD string_set :elements",
ExpressionAttributeValues={":elements": new_str_set},
)

How to set group = true in couchdb

I am trying to use map/reduce to find the duplication of the data in couchDB
the map function is like this:
function(doc) {
if(doc.coordinates) {
emit({
twitter_id: doc.id_str,
text: doc.text,
coordinates: doc.coordinates
},1)};
}
}
and the reduce function is:
function(keys,values,rereduce){return sum(values)}
I want to find the sum of the data in the same key, but it just add everything together and I get the result:
<Row key=None, value=1035>
Is that a problem of group? How can I set it to true?
Assuming you're using the couchdb package from pypi, you'll need to pass a dictionary with all of the options you require to the view.
for example:
import couchdb
# the design doc and view name of the view you want to use
ddoc = "my_design_document"
view_name = "my_view"
#your server
server = couchdb.server("http://localhost:5984")
db = server["aCouchDatabase"]
#naming convention when passing a ddoc and view to the view method
view_string = ddoc +"/" + view_name
#query options
view_options = {"reduce": True,
"group" : True,
"group_level" : 2}
#call the view
results = db.view(view_string, view_options)
for row in results:
#do something
pass

Categories