Hi Nickolas,
On Fri, Feb 19, 2010 at 2:14 PM, Nickolas Daskalou <[email protected]>wrote:
> Hi Nick,
>
> I have something like this:
>
>
> class Foo(db.Model):
> name = db.StringProperty()
> ...
>
> class Bar(db.Model):
> foo = db.ReferenceProperty(Foo, collection_name='bars')
> foo_name = db.StringProperty()
>
> class Baz(db.Model):
> foo = db.ReferenceProperty(Foo, collection_name='bazs')
> foo_name = db.StringProperty()
>
>
> I have added a hook in my application which calls a post_put() method on
> all instances that are put() into the Datastore (after they are put,
> obviously).
>
> In the post_put() of a Foo entity, I want to get all "reverse" referenced
> Bar and Baz entities, and update their foo_name with the Foo entity's name.
> However, I only need to update the Bar and Baz entities who's foo_name value
> != the Foo entity's name.
>
Will this be an all-or-nothing proposition? Eg, if the put of 'foo' changed
the foo_name, they'll all need updating, otherwise none of them will? In
that case, you'd be better off checking if it's changed, and updating them
all (without the inequality filter) if it did change.
> So I could do something like:
>
>
> class Foo(db.Model):
> ...
> def post_put():
> for collection_name in ('bars', 'bazs'):
> q = getattr(self, collection_name)
> q.filter('foo_name !=', self.name)
> # Fetch, then update.....
>
>
> This works fine, except I need to add a new index each time I do this,
> since "q" has two filters, one equality (an implied filter('foo =', self))
> and one inequality.
>
> Instead, I would like to get the Model class associated with each
> collection_name and just add one inequality filter, ie:
>
>
> class Foo(db.Model):
> ...
> def post_put():
> for collection_name in ('bars', 'bazs'):
> model_class = self.get_model_class_for_collection(collection_name)
> q = model_class.all().filter('foo_name !=', self.name)
> # Fetch, then update.....
> def get_model_class_for_collection(collection_name):
> q = getattr(self, collection_name)
> return q.model_class() # This is the Query method I want
>
>
> This way I do not need to create a new index each time I do this.
>
The above will change every single Bar and Baz entity that doesn't match
foo's entity name, though, including those that have nothing to do with the
foo you modified.
>
> Can you suggest a similar no-new-index way of doing this?
>
Depending on how many Bar and Baz entities there are per Foo, you could just
drop the inequality and filter them out once they're fetched.
>
> I also thought about doing this (only get_model_class_for_collection() has
> changed):
>
>
> class Foo(db.Model):
> ...
> def post_put():
> for collection_name in ('bars','bazs'):
> model_class = self.get_model_class_for_collection(collection_name)
> q = model_class.all().filter('foo_name !=', self.name)
> # Fetch, then update.....
> def get_model_class_for_collection(collection_name):
> q = getattr(self, collection_name)
> entity = g.get()
> return entity.__class__
>
>
Given that you're already hard-coding in the list of collections, you could
avoid the need for a 'get_model_class_for_collection' method by replacing
the loop with:
"for model_class in (Bar, Baz):"
>
> Forgetting about the extra Datastore get() required, the method above could
> cause problems when it comes to PolyModel entities, because (correct me if I
> am wrong) when PolyModel entities come back from the Datastore they are
> instances of the deepest subclass in the entity's inheritance chain, so
> returning entity.__class__ (in the last line above) will limit the results
> of the query (with the single inequality filter) to entity's of the original
> entity's PolyModel subclass. I hope that makes sense.
>
> Nick, I would love to get your ideas on this. Also, I'm no Python expert so
> if I'm overcomplicating things please let me know.
>
> Cheers,
>
> Nick
>
>
> On 19 February 2010 22:50, Nick Johnson (Google)
> <[email protected]>wrote:
>
>> Hi Nickolas,
>>
>> There's no public interface for this. Why do you need to do it?
>>
>> -Nick Johnson
>>
>> On Fri, Feb 19, 2010 at 11:28 AM, Nickolas Daskalou <[email protected]>wrote:
>>
>>> Is there an "official" way to get the Model class from a Query
>>> instance? I had a look through the online docs and couldn't find anything.
>>>
>>> In the SDK code however, the Model class of a Query instance can be
>>> retrieved from the _model_class attribute of the Query instance, eg:
>>>
>>> q = MyModel.all()
>>> ....
>>> model_class = q._model_class # == MyModel
>>>
>>> I don't really want to do it this way because since this is not
>>> documented anywhere, I'm afraid that this implementation may change in the
>>> future.
>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups
>>> "Google App Engine" group.
>>> To post to this group, send email to [email protected].
>>> To unsubscribe from this group, send email to
>>> [email protected]<google-appengine%[email protected]>
>>> .
>>> For more options, visit this group at
>>> http://groups.google.com/group/google-appengine?hl=en.
>>>
>>
>>
>>
>> --
>> Nick Johnson, Developer Programs Engineer, App Engine
>> Google Ireland Ltd. :: Registered in Dublin, Ireland, Registration Number:
>> 368047
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Google App Engine" group.
>> To post to this group, send email to [email protected].
>> To unsubscribe from this group, send email to
>> [email protected]<google-appengine%[email protected]>
>> .
>> For more options, visit this group at
>> http://groups.google.com/group/google-appengine?hl=en.
>>
>
> --
> You received this message because you are subscribed to the Google Groups
> "Google App Engine" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected]<google-appengine%[email protected]>
> .
> For more options, visit this group at
> http://groups.google.com/group/google-appengine?hl=en.
>
--
Nick Johnson, Developer Programs Engineer, App Engine
Google Ireland Ltd. :: Registered in Dublin, Ireland, Registration Number:
368047
--
You received this message because you are subscribed to the Google Groups
"Google App Engine" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-appengine?hl=en.