Reputation: 16825
Ok a little implementation problem I have enccountrered since I am migrating from SQL to noSQL HDR.
I have a model called page:
class Page(db.Model):
url = db.StringProperty(required=True)
title = db.StringProperty()
enable_login = db.BooleanProperty(required=True, default=True)
owner = db.ReferenceProperty(Person, collection_name = 'pages')
date_created = db.DateTimeProperty(auto_now_add=True)
date_edited = db.DateTimeProperty(auto_now=True)
Everytime a user registers, then a page is created with a unique url that is not used as the key_name for several reason that I am willing to discuss.
Inside a transaction:
unique_url=hashlib.md5(str(person.key())).hexdigest()
page = Page(key_name=unique_url,parent=person, owner=person, title="Home page", name=person.nick_name, url=unique_url)
Now my problem arises when a user tries to update his page url. The user is only allowed to change his page url only once. The user POSTS a new page url, then the server checks if that url exists and if not updates the user page.
Again inside a transaction due to the fact that I dont want any duplicate urls:
def validate_page_properties(self, page):
if not re.match("\A[A-Za-z]+\Z", page.url) or len(page.url) < 4 or len(page.url) > 20:
return False
page = Page.all().filter("url =",page.url).get()
Error:
Only ancestor queries are allowed inside transactions.
How can I overcome this implementation error?
I tried setting the url as the the key_name since it's unique (enforced) but I still need the complete key due to the fact the the parent of every page is the user. I can change to pages not having a parent, but that could later create a problem again with transactions that I might need.
Any suggestions? Am I missing something here?
Upvotes: 1
Views: 895
Reputation: 80330
First you should understand GAE transactions and what can be done within transaction.
In your case you already set a person to be parent of page, so you should only set this in the query:
page = Page.all().ancestor(person).filter("url =",page.url).get()
Update: you can not use a person-scoped transaction and at the same time check for globally unique user-generated string. Either you have a string wich is person-unique (= nonsense) or scope must be global. You could achieve this by:
Upvotes: 1