django-mongodb-engine can't update an object - python

I am writing a Django-based back end using django-mongodb-engine for an android app and I'm trying to get data from a PUT request to update a record in my database. I'm getting a username and filtering the database for the user object with that name (successfully), but the save function doesn't seem to be saving the changes. I can tell the changes aren't being saved because when I go onto mLab's online database management tool the changes aren't there.
Here's the code:
existing_user = User.objects.filter(userName = user_name)
if existing_user == None:
response_string += "<error>User not identified: </error>"
elif (existing_user[0].password != user_pwd):
response_string += "<error>Password error.</error>"
#if we have a validated user, then manipulate user data
else:
existing_user[0].star_list.append(new_star)
existing_user[0].save()
I'm not getting any error messages, but the data remains the same. The star_list remains empty after the above. In fact, as a test I even tried replacing the else clause above with:
else:
existing_user[0].userName = "Barney"
existing_user[0].save()
And following this call, the existing_user[0].userName is still it's original value ("Fred", rather than "Barney")!

Found an answer to this question. I'm not sure why it wasn't working as posted, but there were problems trying to access the object through the list... in other words the following didn't work:
existing_user[0].userName = "Barney"
existing_user[0].save()
But this did:
found_user = existing_user[0]
found_user.userName = "Barney"
found_user.save()
Based on my understanding of Python lists, either one should be the same... but maybe some python genius out there can explain why they aren't?

Related

Check if username already exists in database (Python + Pymongo)

I'm trying to make a registration module to use in a larger login/authentication program and I need to make a function that can check if a username already exists in a collection.
I haven't tried much more than this, this is my first real programming project and I'm stuck on this part. I realize I could use in-line dictionary databases, but I want to learn how to integrate 3rd party databases with my programming.
from pymongo import MongoClient
import time
client = MongoClient('localhost', 27017)
loginDB = client["loginDB"]
userCol = loginDB["userCol"]
##Username##
print('Choose A Unique Username')
time.sleep(1.2)
unameInput = input("Enter Username: ")
unameList = {'Username': unameInput}
unameQuery = {}
unameQuery2 = userCol.find_one({'Username.Username': {'$gt': 'a'}})
if unameInput != unameQuery2:
print('Name is Available | Accepted!')
allList = {'Username': unameList}
userCol.insert_one(allList)
else:
print('Sorry, Please Try Again.')`
The expected result is to search the database for everything that starts with the letter "a", forward. If the input (unameInput) does not equal anything in the query result (unameQuery2), then print "Username is available". If anything in the query matches the input, then print "Please try again", however, it's accepting everything that is input and exiting the code.
You are using find_one() to find one entry in Username and then checking if unameInput is equal to it. If it's not an exact match, it will execute the code for name is available.
Try find() instead as this will iterate over all the documents in the collection.
unameQuery2 = userCol.find()
if unameInput not in unameQuery2:
# do something
I figured it out, I was putting dictionaries inside of dictionaries inside of documents, as well as not iterating "allList".

Bulk Undelete CouchDB Docs with CouchDB-Python

I accidentally deleted all the docs in a CouchDB database and I want to undelete them.
CouchDB version = 2.2.0
Python = 2.7 and I'm using the python-couchDB library.
My CouchDB is not doing any compaction and 1260 documents are listed in the doc_del_count when I call /couchip:5984/my_db
I followed directions here:
Retrieve just deleted document
and adjusted it in Python like so:
docs_to_put_back = []
ids_to_put_back = []
for id in db.changes()['results']:
ids_to_put_back.append(id)
for id in ids_to_put_back:
rev = db.get(id, revs=True, open_revs='all')
current_revision = rev[0]['ok']['_rev']
current_number = rev[0]['ok']['_revisions']['start']
rev_id = rev[0]['ok']['_revisons']['ids'][1] # The last revision id
old_doc = db.get(id, rev=str(current_number-1)+'-'+rev_id)
I started printing old_doc from here and most of the time, it returned a NoneType but I did see that some were printing out the documents that I wanted to restore so I added this to the code:
if old_doc != None:
db.save(old_doc, rev=current_revision)
This didn't work and nothing restored to my database. Now when I try to look at all revisions of these documents, I can't seem to return anything but a NoneType when I call old_doc. I tried looping through all the revisions like this:
for id in ids_to_put_back:
rev = db.get(_id, revs=True, open_revs='all')
current_revision = rev[0]['ok']['_rev']
current_number = rev[0]['ok']['_revisions']['start']
rev_list = rev[0]['ok']['_revisions']['ids']
counter = 1
for revision in rev_list[1:]:
old_doc = db.get(_id, rev=str(current_number-counter)+'-'+revision)
if old_doc == None:
counter += 1
continue
elif old_doc != None:
docs_to_put_back.append(old_doc)
break
else:
pass
docs_to_put_back is returning an empty list. From my understanding, if my database is not compacting, I should be able to get the old documents if I have their old revision numbers. However, from what I've been reading, it seems like this may not be the case.
I've also tried putting the document back into the database first and then tried to get an old revision number with curl like so:
curl -X PUT http://localhost:5984/db/id
{"ok": true, "id":"id", "rev":""3-b7ff1b0135c051822dd2958aec1a1b9c"}
curl -X GET http://localhost:5984/db/id?rev=2-1301c6dd3257decf978655f553ae8fa4
{"_id":"id", "rev":"2-1301c6dd3257decf978655f553ae8fa4", "_deleted":true}
curl -X GET http://localhost:5984/db/id?rev=1-42283a6b30639b12adddb814ba9ee4dc
{"error":"not_found", "reason":"missing"}
Am I hosed? Does CouchDB not have access to all the old revisions (which I've read is a kind of a misnomer)?
This wasn't my best day so if you can please help, that would be awesome! Thank you!
Turns out I am hosed so no you can't get those deleted documents back if you wait too long. By default, CouchDB will check your databases every hour and run compaction if it's over something like 131 kb. After that happens, all my old revisions are "missing."
If only CouchDB had an Undo button for user error....

OdooV8 - Why does it take so long to create a record in 'res_partner' in my case

I recently started to develop with odoo8 and I've met a problem.
My problem is that I have two classes : 'helpdesk' and 'res_partner' and I don't know why my code stuck for a long time when I create a new record in 'res_partner' but when I comment this block of codes (below) my code works great.
self.env['res.partner'].create({
'name': nameFmt,
'firstname': self.firstNameOfUser.strip().lower().title(),
'lastname': self.lastNameOfUser.strip().upper(),
'birthdate': newDateFmt,
'birth_place': self.pBirthOfUser,
'is_company': False
})
'helpdesk' class has several fields and methods to get information, and computes them from the user inputs. Once the information computed, I create my record which is a new partner.
How I tried to solve my problem, I :
Launched odoo in shell mode with '--debug' option and a pdb where the code is stuck (it's stuck at the 'create' method as I said)
Read some threads and documentations about my problem, but most are in v7 for the create method and anybody has been stuck like this for the creation of a record
Checked each value that I sent to create my new record
Saw the behavior of records and how they are stored with phpPgAdmin
For more information, this is my entire method definition :
#api.one
def addPartnerInDB(self):
if (not self.firstNameOfUser or
not self.lastNameOfUser or
not self.dobOfUser or
not self.pBirthOfUser):
raise ValidationError(u"Tous les champs sp\u00E9cifi\u00E9s pour "
u"cette demande doivent \u00EAtre remplis !")
# Avoid concurrent drop-down
self.dropDownList1 = False
self.dropDownList3 = False
# Get every partners
listOfPartners = self.env['res.partner'].search(
[
('is_company', '=', False)
]
)
# Avoid useless compute for each iteration
newDateFmt = u"".join(datetime.datetime\
.strptime(str(self.dobOfUser), "%Y-%m-%d")\
.strftime("%d/%m/%Y"))
newFNameFmt = self.firstNameOfUser.strip().replace(" ", "-").lower()
newLNameFmt = self.lastNameOfUser.strip().replace(" ", "-").lower()
newBPFmt = self.pBirthOfUser.strip().replace(" ", "-").lower()
matchedPartners = []
# Fetch partner specified by the user
for p in listOfPartners:
if (newFNameFmt == p.firstname.strip().replace(" ", "-").lower() and
newLNameFmt == p.lastname.strip().replace(" ", "-").lower()):
matchedPartners.append(p)
partnerAlreadyExist = False
# If the list is not empty, then the fetch is enhance
if (matchedPartners):
for m in matchedPartners:
partnerDOB = False
partnerBP = False
if (not isinstance(m.birthdate, bool)):
if (newDateFmt == m.birthdate):
partnerDOB = True
if (not isinstance(m.birth_place, bool)):
if ((newBPFmt
== m.birth_place.strip().replace(" ", "-").lower())):
partnerBP = True
# If one of them it's true, the user already exist
if (partnerDOB or partnerBP):
partnerAlreadyExist = True
# Avoid useless iteration
break
# If the user specified doesn't exist he's created
if (not partnerAlreadyExist):
# Encode the string to avoid UnicodeError and further string errors
nameFmt = (self.lastNameOfUser.strip().upper(),
+ u" "
+ self.firstNameOfUser.strip().lower().title())
self.env['res.partner'].create(
{
'name': nameFmt,
'firstname': self.firstNameOfUser.strip().lower().title(),
'lastname': self.lastNameOfUser.strip().upper(),
'birthdate': newDateFmt,
'birth_place': self.pBirthOfUser,
'is_company': False
}
)
else:
raise ValidationError(u"L'utilisateur renseign\u00E9 "
u"existe d\u00E9j\u00E0 !")
EDIT
After several attempts to debug my code with pdb, I noticed that something went wrong in the for statement when I compare firstnames and lastnames :
for p in listOfPartners:
if (newFNameFmt == p.firstname.strip().replace(" ", "-").lower()
and newLNameFmt == p.lastname.strip().replace(" ", "-").lower()):
# Append element
Indeed, pdb blocks (2/3 sec) for each start of for statement before it gives me the hand back.
For example :
(pdb) ->if (newFNameFmt == p.firstname.strip().replace(" ", "-").lower() and
# stuck 2-3 seconds
(pdb) -> newLNameFmt == p.lastname.strip().replace(" ", "-").lower()):
This behavior continues for about the first iterations of the for statement, after this amount of iterations, this behavior is no longer adopted for the rest of the iterations. Once I arrived at the create statement (with pdb), the creation record is miraculously unlocked and the code works.
I still don't know why this problem occurs and I still don't know how to solve it.
you got that issue because maybe you have compare 2 different type! In your case, you maybe try to compare between res_partner object and string type or another! That should be res.partner(2973,).id or res.partner(2973,).name ....
I've found an answer for my question, and I think to know where the problem came from.
Where was my problem
So the problem came from my first for statement which is :
listOfPartners = self.env['res.partner'].search(
[
('is_company', '=', False)
]
)
for p in listOfPartners:
if (newFNameFmt == p.firstname.strip().replace(" ", "-").lower()
and newLNameFmt == p.lastname.strip().replace(" ", "-").lower()):
matchedPartners.append(p)
Theoretically nothing could be wrong with the for and search statements since they do what I want to do. But the problem is that each iteration that the program did in this for was 'n' queries sent to the PostgresSQL server (where n corresponds to the number of time that p is used in each iteration. In my case n = 2). This issue escalated quickly since search returned me about a thousand of partners (which are represented by id of each record saved in res.partner that matched the search query). So in the for this corresponds to thousands of queries that I sent in a very short time to the PostgreSQL server, and it seems that this server couldn't handle this amount of requests in a very short time.
So the problem was not the code in himself, but the behavior that I gave to him. The result of that behavior gave another behavior to the PostgreSQL for the further queries that I will give via Odoo, like create.
How I solved it
The solution for me was to use the psycopg2 module. This module allowing communication with the postgreSQL server. The main difference between both in my case was that Odoo stayed in communication with the PostgreSQL server even if I used search to get only values that I wanted. While psycopg2 gived me a list (of tuples) that only contains "real" values and not an id like Odoo gave me with search.
Once again, I don't know if the solution that I choosed was the best or if the issue came from there like I said above but this solution works well for me and I hope it will help others users stuck in a problem with the same behavior.

Trying to change a username in Python Google Admin SDK

I'm trying to change a username using the Admin SDK. I'm trying the following code to update this, using a dict object to store the new info, and using patch to update:
userinfo['primaryEmail'] = D['new_user'] + '#' + D['domain']
appsservice.users().patch(userKey = userEmail, body=userinfo)
It doesn't seem to be working, when I look at the admin console. The original username remains unchanged. I'm just wondering if I'm using the correct method. Should I be updating a different variable than primaryEmail or without using the domain affiliation? Seems like I'm just missing something rather obvious.
Thanks,
Tom
Add:
.execute()
To the end of the 2nd line to actually execute the api operation.

Item won't update in database

I'm writing a method to update several fields in multiple instances in my database. For now, I'm trying to get it to work just for one.
My user uploads a CSV file with all the information to change (including the pk). I've written the function that parses all the information, and this all works fine. I can even assign the data to an item, and if I print it from that function, it comes out correctly. However, when I save the updates (using item.save()) nothing seems to change in the database.
Here's a very stripped down version of the method. I really don't know why it isn't working. I've done something very similar in other spots (getting data through a form, setting the field, calling save, and then displaying the changed information), and I've used a very similar CSV uploading technique to create new entries.
Small piece of relevant code:
reader = csv.reader(f)
for row in reader:
pk = row[0]
print(pk)
item = POObject.objects.get(pk=pk)
p2 = item.purchase2
print item.purchase.requested_start_date
print p2.requested_start_date
requested_start_date=row[6]
requested_start_date = datetime.datetime.strptime(requested_start_date, "%d %b %y")
print requested_start_date
p2.requested_start_date = requested_start_date
p2.save()
print p2.requested_start_date
item.purchase2 = p2
item.save()
print item.purchase.requested_start_date
return pk
Obviously I have lots of prints in there to find where stuff went wrong. Basically what I find is that if I look at item, it looks fine, but if I query the server again (after saving) i.e. dong item2=POObject.objects.get(pk=pk) it won't have had any updates. Does anyone have any idea why save() isn't doing anything?
UPDATE:
The mystery continues.
If I update a field that isn't contained within an FK relation (say, a text field or something), everything seems to work fine. However, what I really need to do is update an item, and then set that item as the fk relation to the main item in question. I'm not sure why this isn't working in the normal way (updating the internal item, saving it, and then setting the fk to that new, updated item).
Whoa. Feel a little ashamed that I didn't figure this out. I had forgotten exactly how I had designed one of my models, and there was another object within it that needed to be updated, but I wasn't saving it.

Categories