在 gcloud api 中按键查询 google 数据存储
Query google datastore by key in 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
似乎不是 supported type:
value (int, str, bool, float, NoneType, :classdatetime.datetime
) – The value to filter on.
是否可以为关键属性添加过滤器?
我做了更多的调查,试图找出这里到底发生了什么。我不确定这对我目前理解这个问题是否有帮助,但也许对其他人有帮助。
我模拟了各个库中的底层调用,以记录正在序列化并发送到服务器的协议缓冲区。对于 GAE,它似乎是 datastore_query 模块中的 Batch.create_async
。
对于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 查询 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 库时的一个细微错误:
查看您的模型定义,您会看到 user = ndb.KeyProperty('User')
。这实际上并不是说 user
属性 是 User
实体的键,而是它应该以 属性 名称 User
存储在 Datastore 中].您可以在 属性 名称(区分大小写)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)
我正在尝试使用我刚刚发现的 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
似乎不是 supported type:
value (int, str, bool, float, NoneType, :class
datetime.datetime
) – The value to filter on.
是否可以为关键属性添加过滤器?
我做了更多的调查,试图找出这里到底发生了什么。我不确定这对我目前理解这个问题是否有帮助,但也许对其他人有帮助。
我模拟了各个库中的底层调用,以记录正在序列化并发送到服务器的协议缓冲区。对于 GAE,它似乎是 datastore_query 模块中的 Batch.create_async
。
对于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 查询 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 库时的一个细微错误:
查看您的模型定义,您会看到 user = ndb.KeyProperty('User')
。这实际上并不是说 user
属性 是 User
实体的键,而是它应该以 属性 名称 User
存储在 Datastore 中].您可以在 属性 名称(区分大小写)User
.
如果要将密钥限制为单一种类,则需要使用 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)