【问题标题】:Python Google App Engine query inside transaction without ancestor?没有祖先的交易中的Python Google App Engine查询?
【发布时间】:2012-12-17 10:50:22
【问题描述】:

好吧,自从我从 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)

每次用户注册时,都会创建一个带有 unique url 的页面,由于我愿意讨论的几个原因,该 url 不用作 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)

现在,当用户尝试更新他的页面 url 时,我的问题就出现了。用户只允许更改他的页面 url 一次。 用户发布一个新的页面 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,因为它是唯一的(强制执行的),但我仍然需要完整的密钥,因为每个页面的父级都是用户。 我可以更改为没有父页面的页面,但这可能会在以后再次对我可能需要的事务造成问题。

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

【问题讨论】:

    标签: python google-app-engine transactions implementation


    【解决方案1】:

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

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

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

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

    1. 使用全局父级 - 具有单个实体 UniqueUrlParent,它是所有用户提交的 Url 的父级。这将成为一个瓶颈,因为写入限制为每个实体组 5 次写入/秒(您只有一个全局)。
    2. 使用 Urls 作为键 - 但您说您不想这样做。请详细说明为什么不呢?您可以使用某种两种方式的哈希来使这种方式不可读。

    【讨论】:

    • 但这不是 OP 想要的,因为他需要 URL 在数据存储中是唯一的,而不是每个人。
    • 使用 url 作为键无济于事,因为我仍然需要人的密钥来构造完整的密钥,因为每个页面都是人的孩子。
    • 为什么它需要是 person 的孩子?它只能包含对人员的引用(键)。
    • @PeterKnego 为了能够与人和页面以及页面的任何其他子级等运行未来的交易。这是个坏主意吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-21
    相关资源
    最近更新 更多