Python, CouchDb: how to Update already existing document by ID - python

I am trying to update an already existing document by ID. My intention is to find the doc by its id, then change its "firstName" with new value coming in "json", then update it into the CouchDB database.
Here is my code:
def updateDoc(self, id, json):
doc = self.db.get(id)
doc["firstName"] = json["firstName"]
doc_id, doc_rev = self.db.save(doc)
print doc_id, doc_rev
print "Saved"
//"json" is retrieved from PUT request (request.json)
at self.db.save(doc) I'm getting exception as "too many values to unpack".
I am using Bottle framework, Python 2.7 and Couch Query.
How do I update the document by id? what is the right way to do it?

In couchdb-python the db.save(doc) method returns tuple of _id and _rev. You're using couch-query - a bit different project that also has a db.save(doc) method, but it returns a different result. So your code should look like this:
def updateDoc(self, id, json):
doc = self.db.get(id)
doc["firstName"] = json["firstName"]
doc = self.db.save(doc)
print doc['_id'], doc['_rev']
print "Saved"

Related

I am trying to update data but it doesn't get updated in the database

I am new to python and Mongo db. What am I trying to do is that I want to update data in my database and code seems to be working fine. But, still the data doesn't get updated in the database.
I have tried functions like update and update_one etc. But still no luck so far.
#app.route("/users/update_remedy", methods = ['POST'])
def update_remedy():
try:
remedy = mongo.db.Home_Remedies
name = request.get_json()['name']
desc = request.get_json()['desc']
print("S")
status = remedy.update_one({"name" : name}, {"$set": {"desc" : desc}})
print("h")
return jsonify({"result" : "Remedy Updated Successfully"})
except Exception:
return 'error'
It's likely that your update_one call is looking for a document that doesn't exist. If the query on a vanilla update doesn't return any documents then no update operation will be performed. Make sure that a doc with the field {"name" : name}
actually exists. You could also check the return value from the update_one to ensure an update happened. See UpdateResult for details.

Google Datastore Client Parsing in Python

I am hoping to get some help with Parsing data retrieved from the Google DataStore Client in Python.
I am required to create a process in which I have to parse some data taken from the datastore. I am currently calling to retrieve data via this method: https://cloud.google.com/datastore/docs/concepts/entities#retrieving_an_entity
If I am to print what is returned I get the below:
<Entity(u'Example', u'1000') {u'some_data': True, u'some_more_data': False}>
If I could be shown an example on how to best parse the information returned in the Dict I would be very grateful, so that I can take each property and its value in a For Each Loop. I.e:
'some_data': True
Thanks for your time,
Jordan
In Python, properties can be accessed just like object attributes.
For example, after you retrieve your entity:
key = client.key("yourkey")
example = client.get(key)
You can access its properties by their name and use them
print "'some_data': " + example.some_data
print "'some_more_data': " + example.some_more_data
To get a list of an entity's properties, use the instance_properties() method:
for property in example.instance_properties():
value = getattr(example, property)
Read more: https://www.safaribooksonline.com/library/view/programming-google-app/9780596157517/ch04s06.html
I managed to figure out a working solution.
from google.cloud import datastore
datastore_client = datastore.Client()
def parse_example_list():
kind = 'Kind'
name = 'Name'
key = datastore_client.key(kind, name)
returned_entity = datastore_client.get(key)
property_list = {}
for p in returned_entity.items():
property_list[p[0]] = p[1]
return property_list
This returns:
{u'my_first_property': u'My Propertys Value'}
Hope this helps!

How do I retrieve a path's data from firebase database using python?

I have this firebase database structure
I want to print out the inventory list(Inventory) for each ID under Businesses.
So I tried this code
db = firebase.database()
all_users = db.child("Businesses").get()
for user in all_users.each():
userid = user.key()
inventorydb = db.child("Businesses").child(userid).child("Inventory")
print(inventorydb)
but all I got is this
<pyrebase.pyrebase.Database object at 0x1091eada0>
what am I doing wrong and how can I loop through each Business ID and print out their inventory?
First, you're printing a Database object. You need to get the data still.
You seem to already know how to get that as well as the children. Or you only copied the examples without understanding it...
Either way, you can try this
db = firebase.database()
businesses = db.child("Businesses")
for userid in businesses.shallow().get().each():
inventory = businesses.child(userid).child("Inventory").get()
print( inventory.val() )
On a side note, National_Stock_Numbers looks like it should be a value of the name, not a key for a child

Assigning UUID and checking duplicates for web scraper in mongodb

I am building a web scraper and trying to assign an entity a UUID.
Since one entity may be scraped at different times, I want to store the initial UUID along with the extracted id from the webpage
// example document
{
"ent_eid_type": "ABC-123",
"ent_uid_type": "123e4567-aaa-123e456"
}
below is code that runs for every id field that is found in a scraped item
# if the current ent_eid_type is a key in mongo...
if db_coll.find({ent_eid_type: ent_eid}).count() > 0:
# return the uid value
ent_uid = db_coll.find({ent_uid_type: ent_uid })
else:
# create a fresh uid
ent_uid = uuid.uuid4()
# store it with the current entity eid as key, and uid as value
db_coll.insert({ent_eid_type: ent_eid, ent_uid_type: ent_uid})
# update the current item with the stored uid for later use
item[ent_uid_type] = ent_uid
Console is returning KeyError: <pymongo.cursor.Cursor object at 0x104d41710>. Not sure how to parse the cursor for the ent_uid
Any tips/ suggests appreciated!
Pymongo Find command returns a cursor object you need to iterate or access to get the object
Access the first result (you already checked one exists), and access the ent_uid field.
Presumably, you're going to search on EID type, with ent_eid not ent_uid. No reason to search if you already have it.
ent_uid = db_coll.find({ent_eid_type: ent_eid })[0]['ent_uid']
or don't worry about the cursor and use the find_one command instead (http://api.mongodb.com/python/current/api/pymongo/collection.html#pymongo.collection.Collection.find_one)
ent_uid = db_coll.find_one({ent_eid_type: ent_eid })['ent_uid']

Updating DataStore JSON values using endpoints (Python)

I am trying to use endpoints to update some JSON values in my datastore. I have the following Datastore in GAE...
class UsersList(ndb.Model):
UserID = ndb.StringProperty(required=True)
ArticlesRead = ndb.JsonProperty()
ArticlesPush = ndb.JsonProperty()
In general what I am trying to do with the API is have the method take in a UserID and a list of articles read (with an article being represented by a dictionary holding an ID and a boolean field saying whether or not the user liked the article). My messages (centered on this logic) are the following...
class UserID(messages.Message):
id = messages.StringField(1, required=True)
class Articles(messages.Message):
id = messages.StringField(1, required=True)
userLiked = messages.BooleanField(2, required=True)
class UserIDAndArticles(messages.Message):
id = messages.StringField(1, required=True)
items = messages.MessageField(Articles, 2, repeated=True)
class ArticleList(messages.Message):
items = messages.MessageField(Articles, 1, repeated=True)
And my API/Endpoint method that is trying to do this update is the following...
#endpoints.method(UserIDAndArticles, ArticleList,
name='user.update',
path='update',
http_method='GET')
def get_update(self, request):
userID = request.id
articleList = request.items
queryResult = UsersList.query(UsersList.UserID == userID)
currentList = []
#This query always returns only one result back, and this for loop is the only way
# I could figure out how to access the query results.
for thing in queryResult:
currentList = json.loads(thing.ArticlesRead)
for item in articleList:
currentList.append(item)
for blah in queryResult:
blah.ArticlesRead = json.dumps(currentList)
blah.put()
for thisThing in queryResult:
pushList = json.loads(thisThing.ArticlesPush)
return ArticleList(items = pushList)
I am having two problems with this code. The first is that I can't seem to figure out (using the localhost Google APIs Explorer) how to send a list of articles to the endpoints method using my UserIDAndArticles class. Is it possible to have a messages.MessageField() as an input to an endpoint method?
The other problem is that I am getting an error on the 'blah.ArticlesRead = json.dumps(currentList)' line. When I try to run this method with some random inputs, I get the following error...
TypeError: <Articles
id: u'hi'
userLiked: False> is not JSON serializable
I know that I have to make my own JSON encoder to get around this, but I'm not sure what the format of the incoming request.items is like and how I should encode it.
I am new to GAE and endpoints (as well as this kind of server side programming in general), so please bear with me. And thanks so much in advance for the help.
A couple things:
http_method should definitely be POST, or better yet PATCH because you're not overwriting all existing values but only modifying a list, i.e. patching.
you don't need json.loads and json.dumps, NDB does it automatically for you.
you're mixing Endpoints messages and NDB model properties.
Here's the method body I came up with:
# get UsersList entity and raise an exception if none found.
uid = request.id
userlist = UsersList.query(UsersList.UserID == uid).get()
if userlist is None:
raise endpoints.NotFoundException('List for user ID %s not found' % uid)
# update user's read articles list, which is actually a dict.
for item in request.items:
userslist.ArticlesRead[item.id] = item.userLiked
userslist.put()
# assuming userlist.ArticlesPush is actually a list of article IDs.
pushItems = [Article(id=id) for id in userlist.ArticlesPush]
return ArticleList(items=pushItems)
Also, you should probably wrap this method in a transaction.

Categories