在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 == 'me@domain.com').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', '=', '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不是受支持的类型:

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

是否可以为关键属性添加筛选器?


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

我已经模拟了各个库中的基础调用,以记录正在序列化并发送到服务器的协议缓冲区。 对于 GAE,它似乎Batch.create_async在datastore_query模块中。

对于gcloud,这是datastore.Client.connection.run_query方法。 查看生成的协议缓冲区(匿名),我看到:

云查询 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 查询 pb.

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

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

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

所有ndb属性都接受单个位置参数,该参数在数据存储中指定属性的名称

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

如果要将密钥限制为单个类型,则需要使用 kind 选项指定它。

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)

相关内容

  • 没有找到相关文章

最新更新