Python Google App Engine查询内部事务没有祖先?

时间:2012-12-17 10:50:22

标签: python google-app-engine transactions implementation

好的一点实现问题我已经加密了,因为我从SQL迁移到noSQL HDR。

我有一个名为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)

每次用户注册时,都会创建一个页面,其中包含唯一网址,该网址由于我愿意讨论的几个原因而未用作key_name。

在交易中:

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)

现在,当用户尝试更新其网页网址时,我的问题就出现了。用户只能更改其页面网址一次。 用户POSTS一个新的页面URL,然后服务器检查该URL是否存在,如果没有更新用户页面。

再次在交易中,因为我不想要任何重复的网址:

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()

错误:

Only ancestor queries are allowed inside transactions.

如何克服此实现错误?

我尝试将url设置为key_name,因为它是唯一的(强制执行),但由于每个页面的父级都是用户,我仍然需要完整的密钥。 我可以更改为没有父级的页面,但之后可能会再次使用我可能需要的事务创建问题。

有什么建议吗?我在这里错过了什么吗?

1 个答案:

答案 0 :(得分:1)

首先,您应该了解GAE transactionswhat can be done within transaction

在您的情况下,您已经将某人设置为页面的父级,因此您只应在查询中设置此项:

 page = Page.all().ancestor(person).filter("url =",page.url).get()

更新:您不能使用人员范围的事务,同时检查全局唯一的用户生成的字符串。要么你有一个人是唯一的(=无意义的)或范围必须是全局的。你可以通过以下方式实现这一目标:

  1. 使用全局父级 - 具有单个实体UniqueUrlParent,它是所有用户提交的Urls的父级。这就成了一个瓶颈,因为写入是每个实体组(每个实体组只有5个)的限制(你只有一个全局实体)。
  2. 使用网址作为密钥 - 但您说您不想这样做。要详细说明为什么不呢?您可以使用某种双向哈希来使这个人无法读取。