python ndb中的用户名不同

时间:2014-09-08 16:15:42

标签: python-2.7 google-app-engine google-cloud-datastore app-engine-ndb

我对使用python ndb有些怀疑。我正在使用proto数据存储区。我有一个用户类

class User( EndpointsModel ):
    name = ndb.StructuredProperty( Name, required=True )
    dateOfBirth = ndb.DateProperty(required=True)
    userName = ndb.StringProperty( required=True )
    emailId = ndb.StringProperty( required=True )

我想根据用户名获取用户实体。当我创建一个新的User对象并执行

user.id = username

我收到错误" ID必须是整数。",我该如何克服这个问题。 user.get_by_id()也会快于 User.query(User.username == username)?

如果我希望所有用户名都是唯一的,我是否必须创建一个用户名实体,并检查新用户是否已经存在,或者是否存在其他整洁有效的用户这样做的方法。

2 个答案:

答案 0 :(得分:4)

听起来您希望实体的唯一键包含并可从用户名中重现,这是一项常见且有用的事情。

要创建具有特定ID的User实体,必须在调用构造函数时设置ID:

username = 'foo'
user = User(id=username)
user.put()

这构造了一个新的实体对象,其键为User: foo(其中键具有一个路径部分,其类型名称为User,字符串foo的ID)。 put()调用会将其保存到数据存储区。

要获取给定用户名的实体,请构建Key,然后尝试get()

key = ndb.Key('User', username)
user = key.get()
if not user:
    # ....

如果它不存在,通常会将这些内容放在一起为给定用户名创建User实体:

key = ndb.Key('User', username)
user = key.get()
if not user:
    user = User(id=username)
    user.put()

建议的做法是在数据存储区事务中执行此操作,因此尝试为同一用户名创建第一个User实体的两个客户端不会在不知情的情况下互相攻击。

将用户名放在密钥中可保证唯一性。是的,通过密钥获取比通过属性查询更快。查询涉及多个步骤以将结果作为键列表获取,然后获取结果实体,即使只有一个结果。您可能希望将用户名存储为索引属性,以防您需要其他类型的查询,但是获取实体或仅执行存在检查仅使用密钥。

答案 1 :(得分:0)

您是如何创建用户实例的?这样做的正确方法是:

newUser = User(id=your_id)

您根本不需要使用newUser.id,它将无法使用。如果您使用现有ID创建新用户,它将替换数据库中的旧用户。您必须找到一种方法来跟踪您使用的ID或给它们不同的父键,在这种情况下,如果父母不同,您可以复制ID。

关于你的第二个问题,我已经阅读了get_by_id()类,它实际上做的是它使用了一个查询。但是,如果您要自己使用查询,则必须确保获取1个实例并从列表中获取第一个元素fetch()User.query().fetch(1)[0])。使用get_by_id()会更容易,或者如果您有密钥,则使用key.get()