代码之家  ›  专栏  ›  技术社区  ›  mgilson

通过gcloudapi中的键查询google数据存储

  •  1
  • mgilson  · 技术社区  · 9 年前

    我正在尝试使用 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 == 'me@domain.com').get()
    data_records = Data.query(Data.user == user.key).fetch()
    

    我想用 g云 :

    from gcloud import datastore
    
    client = datastore.Client(project='my-project-id')
    user_qry = client.query(kind='User')
    user_qry.add_filter('email', '=', 'me@domain.com')
    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 是一个 supported type :

    值(int、str、bool、float、NoneType、:class datetime.datetime )要筛选的值。

    是否可以为关键属性添加过滤器?


    我做了更多的调查,试图弄清楚这里到底发生了什么。我不确定这对我目前理解这个问题是否有帮助,但也许对其他人有帮助。

    我模拟了各个库中的底层调用,以记录正在序列化并发送到服务器的协议缓冲区。对于GAE来说,似乎是 Batch.create_async datastore_query 单元

    对于 g云 ,它是 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
      >
    }
    

    据我所知,这两个库使用的是不同版本的原型,但传递的数据 非常相似。。。

    1 回复  |  直到 9 年前
        1
  •  3
  •   Patrick Costello    9 年前

    这是使用ndb库时的一个微妙错误:

    All ndb properties accept a single positional argument that specifies the property's name in Datastore

    查看模型定义,您将看到 user = ndb.KeyProperty('User') 。这并不是说 user 属性是 User 实体,但它应该以属性名称存储在数据存储中 使用者 。您可以在属性名称为(区分大小写)的gae协议缓冲区查询中验证这一点 使用者 .

    如果要将密钥限制为一种,则需要使用kind选项指定它。

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

    这个 KeyProperty 还支持:

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

    Here is a description of all the magic .

    现在,您的gcloud查询正在查询错误的大小写用户,应该是:

    data_qry = client.query(kind='Data')
    data_qry.add_filter('User', '=', user.key)