基本上,Im要做的是一个数据结构,其中包含用户名、id和datejoined。然后我想要一个“子结构”,其中有用户“文本”和修改日期。用户将拥有此文本的多个实例。

class User(db.Model):
    ID = db.IntegerProperty()
    name = db.StringProperty()
    datejoined = db.DateTimeProperty(auto_now_add=True)

class Content(db.Model):
    text = db.StringProperty()
    datemod= db.DateTimeProperty(auto_now_add = True)

代码设置是否正确?

最佳答案

你会遇到的一个问题是,使User.ID唯一将是非常重要的。问题是对数据库的两次写入可能发生在不同碎片上,这两种情况同时检查与唯一性约束匹配的现有条目并且不发现任何条目,然后两者创建相同的条目(关于唯一属性),然后您有无效的数据库状态。为了解决这个问题,appengine提供了一种确保某些数据存储实体始终放在同一台物理机器上的方法。
为此,可以使用实体键告诉google如何组织实体。假设您希望用户名是唯一的。将User更改为如下所示:

class User(db.Model):
    datejoined = db.DateTimeProperty(auto_now_add=True)

是的,就是这样。没有用户名,因为它将在密钥中使用,所以不需要单独显示。如果你愿意,你可以这样做。。。
class User(db.Model):
    datejoined = db.DateTimeProperty(auto_now_add=True)

    @property
    def name(self):
        return self.key().name()

要创建User的实例,现在需要做一些不同的事情,需要在init方法中指定key_name
someuser = User(key_name='john_doe')
...
someuser.save()

好吧,你真的想确保用户不会互相覆盖,所以你需要在事务中包装用户创建。首先定义执行必要检查的函数:
def create_user(username):
    checkeduser = User.get_by_key_name(username)
    if checkeduser is not None:
        raise db.Rollback, 'User already exists!'
    newuser = User(key_name=username)
    # more code
    newuser.put()

然后,以这种方式调用它
db.run_in_transaction(create_user, 'john_doe')

要查找用户,只需执行以下操作:
someuser = User.get_by_key_name('john_doe')

接下来,您需要某种方法将内容与其用户关联,反之亦然。一种解决方案是通过将用户声明为内容的父级,将内容放入与用户相同的实体组中。要做到这一点,您根本不需要更改内容,但您创建内容的方式有点不同(就像您对用户所做的那样):
somecontent = Content(parent=User.get_by_key_name('john_doe'))

因此,给定一个内容项,您可以通过检查其密钥来查找用户:
someuser = User.get(somecontent.key().parent())

反过来说,为某个特定用户查找所有内容只需要稍微复杂一点。
allcontent = Content.gql('where ancestor is :user', user=someuser).fetch(10)

关于python - Google App Engine Python数据存储,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4622071/

10-11 02:23
查看更多