google-app-enginedartgoogle-cloud-datastoregoogle-managed-vm

Filter by KeyProperty in Google datastore with Dart


I try to run a query which filters for a KeyProperty. The dart gcloud package I am currently using is version: 0.2.0+8

So for a Model like this:

@Kind(idType: IdType.String)
class Foo extends Model {
  @ModelKeyProperty(indexed: true, required: true)
  Key bar;
}

I would like to run a query like so:

Query query = new Query(db, Foo);
query.filter('bar =', someKey);
var result = query.run();

but I receive following error:

Uncaught error in request handler: ApplicationError: Cannot encode unsupported Key type.
#0      Codec.encodeProperty (package:appengine/src/api_impl/raw_datastore_v3_impl.dart:319:7)
#1      DatastoreV3RpcImpl.query (package:appengine/src/api_impl/raw_datastore_v3_impl.dart:527:43)
#2      Query.run.<anonymous closure> (package:gcloud/src/db/db.dart:232:28)

Solution

  • Assuming

    import 'package:gcloud/datastore.dart' as datastore;
    import 'package:gcloud/db.dart';
    

    In my previous experiments, I remember having to convert the Key (from db.dart) to a datastore.Key. I don't know why this API expects this while the others handle db.Key correctly so I cannot tell whether it is a bug or not but the following should work:

    await db.withTransaction((Transaction transaction) async {
      // convert the key to a datastore key
      datastore.Key datastoreKey = db.modelDB.toDatastoreKey(someKey);
    
      // query by bar key
      Query query = transaction.query(Foo, ancestorKey);
      query.filter('bar =', datastoreKey);
      await query.run().listen((Model model) {
        print(model.key.id);
      }).asFuture();
    });