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
value (int, str, bool, float, NoneType, :class
datetime.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 クエリ pb。
kind: "Data"
Filter {
op: 5
property <
name: "User"
value <
ReferenceValue {
app: "s~app-id"
PathElement {
type: "User"
name: "user_string_id"
}
}
>
multiple: false
>
}
私が知る限り、2 つのライブラリは異なるバージョンの proto を使用していますが、渡されるデータは非常に似ています...