Repository: googleapis/google-cloud-python

Issue:
DISCUSSION: Should dataset ID be set on datastore key?
This question came up in the review in #282 while trying to define the "correct" behavior of `datastore.Key.__eq__`.

The only remaining use of `Key._dataset_id` is in [`to_protobuf`](https://github.com/GoogleCloudPlatform/gcloud-python/blob/b6d3e74a48e8554804ea3d33f53385bbbdb5c4b7/gcloud/datastore/key.py#L53) but #121 seems to indicate that the dataset ID is not needed on a `Key`.

ISTM we should just remove `_dataset_id` from the `Key` class, even though it is returned in the protobuf after an entity is stored/retrieved. @pcostell WDYT?



Discussion:
One issue is that keys may point to other datasets so you can loose that information. So you may want to leave the dataset in there with whatever is populated from the server. I know this complicates equality checks, we plan to fix this in a future version of the API by having a more consistent dataset naming policy.

I can't imagine a situation where someone would have a `Key` object with a dataset ID and have no other way of determining the dataset.

Are there typical cases where one codebase would even interact with multiple datasets at once? (I suppose a developer service could do this, e.g. an analytics tool, but I'd expect such an application to keep datasets carefully distinguished.)

There are very few who currently do so in App Engine, but my guess too is
the analytics sort of app.

I guess I was thinking of something where the analytic app stores in its
datastore an Entity with a key property for one of its customers datasets.
When it gets that entity, it will have a Key property with a dataset that
is different than the dataset that it is stored in. If you drop the
dataset_id completely, the analytic app would not know which dataset the
key corresponded to.

Of course you could just mark it as a know limitation until a future
datastore API version fixes this. If a developer wants to do this now they
can store the external dataset as a separate string property.

On Fri Oct 24 2014 at 3:29:31 PM Danny Hermes notifications@github.com
wrote:

> I can't imagine a situation where someone would have a Key object with a
> dataset ID and have no other way of determining the dataset.
> 
> Are there typical cases where one codebase would even interact with
> multiple datasets at once? (I suppose a developer service could do this,
> e.g. an analytics tool, but I'd expect such an application to keep datasets
> carefully distinguished.)
> 
> —
> Reply to this email directly or view it on GitHub
> https://github.com/GoogleCloudPlatform/gcloud-python/issues/293#issuecomment-60457695
> .

Indeed. And I'd imagine the service would be doing reads only.

How does this sound as a resolution of this issue / discussion?
We make it very clear in the docstring when and how the `_dataset_id` will be set on a `Key`. 

Sounds like we _will_ keep the dataset_id property on a Key?

Can you be more specific with an example of what this decision looks like? I'm just having trouble wrapping my head around the solution proposed...

@jgeewax the solution is to leave the code as-is, just do a better job setting the expectation for the code's behavior.


Resolving patch:
diff --git a/gcloud/datastore/key.py b/gcloud/datastore/key.py
--- a/gcloud/datastore/key.py
+++ b/gcloud/datastore/key.py
@@ -24,7 +24,15 @@ def __init__(self, path=None, namespace=None, dataset_id=None):
 
         :type dataset_id: string
         :param dataset: The dataset ID assigned by back-end for the key.
-                        Leave as None for newly-created keys.
+
+        .. note::
+
+           The key's ``_dataset_id`` field must be None for keys created
+           by application code.  The
+           :func:`gcloud.datastore.helpers.key_from_protobuf` factory
+           will be set the field to an appropriate value for keys returned
+           from the datastore backend.  The application **must** treat any
+           value set by the back-end as opaque.
         """
         self._path = path or [{'kind': ''}]
         self._namespace = namespace


Test patch: