【问题标题】:Get the ID in a child entity of NDB GAE Datastore获取 NDB GAE 数据存储的子实体中的 ID
【发布时间】:2013-10-06 00:54:52
【问题描述】:

我正在获取 NDB Datastore 的 id 上兜圈子。

我已设置webapp2.RequestHandler 来接收电子邮件并获取 ID。基本上我的目标是删除一个实体,但是如果我通过电子邮件地址来获取实体的 ID,我就很难过,因为它给了我刚刚得到的结果。我用 ID 代替了key_name

我尝试通过电子邮件查询查找 ID,但似乎使用查询没有方法属性来查找 ID。

def get(self,email):
  user = users.get_current_user()
  if user:
    user_key = ndb.Key('UserPrefs',user.email())
    contacts = Contact.query(Contact.email==email,ancestor=user_key)
    self.response.write(contacts.id) # there is no attribute such as Contact.id

我试图通过获取密钥来查找 ID,但是当我显示密钥时,它显示了我在 email 变量中的任何值

def get(self,email):
  user = users.get_current_user()
  if user:
    user_key = ndb.Key('UserPrefs',user.email())
    contact_key = ndb.Key('Contact',email,parent=user_key)
    self.response.write(contact_key.id())

真正的问题:那么,鉴于我没有 ID,如果我在实体中找到正确的 ID通过 id 而不是 key_name 保存了我的实体?

这是我正在尝试的混合代码。

def get(self,email):
  user = users.get_current_user()
  if user:
    user_key = ndb.Key('UserPrefs',user.email())
    contact_key = ndb.Key('Contact',email,parent=user_key)
    contacts = Contact.query(Contact.email==email,ancestor=user_key)
    contact = contacts.get()
    contact_key.delete()
    # self.response.write(contact.name) # this works
    self.response.write(contact_key.id()) # this does not work because I do not have the entity id, and I'd like to get it blindfolded. Is there a way?

这是我的联系模型。

class Contact(ndb.Model):
  name = ndb.StringProperty()
  phone = ndb.StringProperty()
  email = ndb.StringProperty()
  dateCreated = ndb.DateTimeProperty(auto_now_add=True)
  dateUpdated = ndb.DateTimeProperty(auto_now=True)

【问题讨论】:

    标签: google-app-engine key app-engine-ndb


    【解决方案1】:

    docs 状态:

    The identifier may be either a key "name" string assigned by the application or an integer numeric ID generated automatically by the Datastore.

    由于您在 Contact 类上定义 name 属性,因此将其用作标识符。 (你不希望这样,因为在现实世界中不同的用户可以有相同的名字)

    因此,如果您希望 NDB 为您的实体生成数字 ID,请将 name 属性重命名为其他名称,例如username.

    更新:让我们一步一步来:

    第一个示例的问题是您试图在Query 上获取id。查询类没有定义 id 属性。你应该打电话给get()

    # get() or fetch() should be called on query to return some data
    contacts = Contact.query(Contact.email==email,ancestor=user_key).get()
    self.response.write(contacts.id) # there is no attribute such as Contact.id
    

    第二段代码的问题是您只是initialising a Key 并提供电子邮件为id - 构造函数的第二个参数是id 并且您提供电子邮件作为值。因此,您将收到电子邮件。另外,这里没有数据库操作。

    【讨论】:

    • 文档似乎没有说明如何在不提供 id 或 key_name 获取 contact_key 的情况下获取 contact_key.id()。有没有办法在不知道实体 ID 或 ID/名称号码的情况下获得contact_key.id()
    • 实体由键标识,其中包含标识符,可以是名称(字符串)或 ID(数字),而不是两者。由于您使用了名称,因此没有 ID。
    • A 文档状态,名为 name 的属性被特殊处理 - 如果您定义它,那么 NDB 将使用它作为标识符。
    • “真正的问题”表明得到contact_key.id()。我知道ndb.Key("UserPrefs",user.email(),"Contact",contact_key.id()) 可能会给我contact_key.id()。但是如果我不知道contact_key.id() 是什么怎么办?我如何获得contact_key.id()?有没有办法让我可以使用contact_key.delete()?使用contact_key.id() 给了我来自ndb.Key("UserPrefs",user.email(),"Contact",email)email 的值。 contact_key.id() 没有给我 ID/Name 值。相反,它意外地给了我我给它的价值,即email
    • 我解释说,如果您在实体类上定义了特殊的 name 属性,则没有 id。要么是 id 要么是 name 不是两者。文档清楚地说明了这一点,我什至引用了相关部分。
    【解决方案2】:

    注意:标识符,它们是idkeyurlsafevalue(用于查询)应该通过 webapp2.RequestHandler 从 HTTP 请求中传递解析的 url 或 HTTP POST、GET、PUT 或 DELETE。

    如果您没有从 HTTP 请求传递的任何标识符,则可能难以访问特定实体(或记录)。因此,重要的是要注意传递某种形式的标识符或值来访问特定实体(或数据库术语中的记录)。

    因此,您可以执行以下操作来获取 id:

    按价值访问:

    def get(self,email):
      user = users.get_current_user()
      if user:
        user_key = ndb.Key('UserPrefs',user.email())
        contacts = Contact.query(Contact.email==email,ancestor=user_key)
        contact = contacts.get()
        id = contact.key.id() # this access the entity id directly because you have the data.
        self.response.write(id)
    

    通过 urlsafe 访问:

    def get(self,urlString):
      user = users.get_current_user()
      if user:
        contact_key = ndb.Key(urlsafe=urlString) #urlString refers to the key of contact
        contact = contact_key.get()
        id = contact.key.id() # this access the entity id directly because you have the data.
        self.response.write(id)
    

    通过 HTTP POST 请求访问:

    def post(self):
      user = users.get_current_user()
      if user:
        user_key = ndb.Key('UserPrefs',user.email())
        email = self.request.get('email')
        contacts = Contact.query(Contact.email==email,ancestor=user_key)
        contact = contacts.get()
        id = contact.key.id() # this access the entity id directly because you have the data.
        self.response.write(id)
    

    【讨论】:

    • 我投反对票,因为您说您无法访问实体 ID。您可以使用contact.key.id() 获取ID。关于如何删除实体的其余答案是正确的。
    • 我后来在继续编程时发现了它。会改变答案。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    • 1970-01-01
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-22
    相关资源
    最近更新 更多