ค้นหา Google Datastore ด้วยคีย์ใน gcloud api

ฉันกำลังพยายามค้นหาข้อมูลบางอย่างโดยใช้ gcloud api ที่ฉันเพิ่งค้นพบ ฉันต้องการสอบถามเกี่ยวกับ KeyPropery เช่น.:

from google.appengine.ext import ndb

class User(ndb.Model):
    email = ndb.StringProperty()

class Data(ndb.Model):
    user = ndb.KeyProperty('User')
    data = ndb.JsonProperty()

ใน GAE ฉันสามารถสืบค้นสิ่งนี้ได้อย่างง่ายดายโดยสมมติว่าฉันมีรหัสผู้ใช้:

user = User.query(User.email == '[email protected]').get()
data_records = Data.query(Data.user == user.key).fetch()

ฉันต้องการทำสิ่งที่คล้ายกันโดยใช้ gcloud:

from gcloud import datastore

client = datastore.Client(project='my-project-id')
user_qry = client.query(kind='User')
user_qry.add_filter('email', '=', '[email protected]')
users = list(user_qry.fetch())
user = users[0]

data_qry = client.query(kind='Data')
data_qry.add_filter('user', '=', user.key)  # This doesn't work ...
results = list(data_qry.fetch())  # results = []

เมื่อดูเอกสารประกอบสำหรับ add_filter ดูเหมือนว่า Entity.key จะเป็น ประเภทที่รองรับ:

ค่า (int, str, bool, float, NoneType, :classdatetime.datetime) – ค่าที่จะกรอง

สามารถเพิ่มตัวกรองสำหรับคุณสมบัติหลักได้หรือไม่?


ฉันได้ตรวจสอบเพิ่มเติมอีกเล็กน้อยเพื่อพยายามคิดว่าเกิดอะไรขึ้นที่นี่จริงๆ ฉันไม่แน่ใจว่าสิ่งนี้จะเป็นประโยชน์สำหรับฉันในการทำความเข้าใจปัญหานี้ในปัจจุบัน แต่อาจเป็นประโยชน์สำหรับบุคคลอื่น

ฉันได้เยาะเย้ยการโทรพื้นฐานในไลบรารีที่เกี่ยวข้องเพื่อบันทึกบัฟเฟอร์โปรโตคอลที่กำลังอนุกรมและส่งไปยังเซิร์ฟเวอร์ สำหรับ GAE ดูเหมือนว่าจะเป็น Batch.create_async ใน datastore_query

สำหรับ gcloud มันคือ datastore.Client.connection.run_query วิธี. เมื่อดูบัฟเฟอร์โปรโตคอลผลลัพธ์ (ไม่ระบุชื่อ) ฉันเห็น:

แบบสอบถาม gcloud pb

kind {
  name: "Data"
}
filter {
  composite_filter {
    operator: AND
    filter {
      property_filter {
        property {
          name: "user"
        }
        operator: EQUAL
        value {
          key_value {
            partition_id {
              dataset_id: "s~app-id"
            }
            path_element {
              kind: "User"
              name: "user_string_id"
            }
          }
        }
      }
    }
  }
}

หน้าแบบสอบถาม GAE

kind: "Data"
Filter {
  op: 5
  property <
    name: "User"
    value <
      ReferenceValue {
        app: "s~app-id"
        PathElement {
          type: "User"
          name: "user_string_id"
        }
      }
    >
    multiple: false
  >
}

ไลบรารีทั้งสองใช้เวอร์ชันที่แตกต่างกันของโปรโตเท่าที่ฉันสามารถบอกได้ แต่ข้อมูลที่ส่งผ่าน ดู คล้ายกันมาก...


comment
ฉันเพิ่มคำตอบ หากวิธีนี้ได้ผลสำหรับคุณ อาจเป็นการดีที่จะยื่นปัญหากับโครงการ gcloud-python เพื่อแก้ไขเอกสารประกอบ (และอาจเป็นข้อความแสดงข้อผิดพลาดที่คุณได้รับในรหัสต้นฉบับของคุณ)   -  person Ed Davisson    schedule 17.03.2016
comment
@EdDavisson - ขอบคุณสำหรับคำตอบ แต่ฉันเข้าใจคำตอบของคุณผิดหรือคุณเข้าใจคำถามของฉันผิด :-) ฉันคิดว่าคุณกำลังตอบคำถาม - ฉันจะสืบค้นตาราง X ด้วยคีย์ของเอนทิตี X ได้อย่างไร ฉันกำลังถามว่าฉันจะสืบค้นตาราง X ด้วยคุณสมบัติที่เก็บคีย์จากเอนทิตีประเภท Y ได้อย่างไร   -  person mgilson    schedule 17.03.2016
comment
คุณพูดถูก -- ฉันกำลังตอบคำถามอื่น คุณสามารถส่งอีเมลไปยังที่อยู่ในโปรไฟล์ของฉันได้หรือไม่? การดูโปรโตดัมพ์ดั้งเดิมที่คุณโพสต์ไว้ด้านบนจะเป็นประโยชน์   -  person Ed Davisson    schedule 18.03.2016


คำตอบ (1)


นี่เป็นข้อผิดพลาดเล็กน้อยในการใช้งานไลบรารี ndb ของคุณ:

คุณสมบัติ ndb ทั้งหมดยอมรับอาร์กิวเมนต์ตำแหน่งเดียวที่ระบุชื่อของคุณสมบัติใน Datastore

เมื่อดูคำจำกัดความของโมเดลของคุณ คุณจะเห็น user = ndb.KeyProperty('User') นี่ไม่ได้บอกว่าคุณสมบัติ user เป็นคีย์ของเอนทิตี User แต่ควรเก็บไว้ใน Datastore ด้วยชื่อคุณสมบัติ User คุณสามารถตรวจสอบสิ่งนี้ได้ในแบบสอบถามบัฟเฟอร์โปรโตคอล gae ของคุณโดยที่ชื่อคุณสมบัติ (คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่) User

หากคุณต้องการจำกัดคีย์ให้เป็นประเภทเดียว คุณต้องระบุคีย์โดยใช้ตัวเลือกประเภท

user = ndb.KeyProperty(kind="User") 

KeyProperty ยังรองรับ:

user = ndb.KeyProperty(User)   # User is a class here, not a string

นี่คือคำอธิบายของความมหัศจรรย์ทั้งหมด.

ขณะนี้ข้อความค้นหา gcloud ของคุณกำลังค้นหาผู้ใช้ที่มีตัวพิมพ์ผิดและควรเป็น:

data_qry = client.query(kind='Data')
data_qry.add_filter('User', '=', user.key)
person Patrick Costello    schedule 18.03.2016
comment
ฉลาดหลักแหลม! ขอบคุณพวกคุณสำหรับความช่วยเหลือ! - person mgilson; 18.03.2016