How To Create Unique Entities

9 views
Skip to first unread message

cwaldbieser

unread,
Jul 20, 2010, 11:42:17 PM7/20/10
to Google App Engine
I have 3 models: A customer account, a service, and a model that
represents a customer's subscription to the service. The subscription
is essentially:

class Subscription(db.Model):
customer = db.ReferenceProperty(Customer)
service = db.ReferenceProperty(Service)

I have a user interface that allows creating or cancelling a
customer's subscription. I want to be able to create a subscription
only if an existing subscription does not already exist. I thought
that a transaction might be the key, but I can't do a query in
transaction unless it is by key or an ancestor query. So I am not
sure what to do.

Any thoughts?

Thanks,
Carl

Robert Kluin

unread,
Jul 21, 2010, 2:51:23 AM7/21/10
to google-a...@googlegroups.com
Hey Carl,
What about just making the subscription's key_name something like "customer.key().id_or_name()-service.key().id_or_name()". That will prevent duplicating subscriptions.


Robert

> --
> You received this message because you are subscribed to the Google Groups "Google App Engine" group.
> To post to this group, send email to google-a...@googlegroups.com.
> To unsubscribe from this group, send email to google-appengi...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en.
>

Robert Kluin

unread,
Jul 21, 2010, 11:00:52 AM7/21/10
to google-a...@googlegroups.com
One other thing, if your subscription model is really that simple you
might look into using a relation index:
http://code.google.com/events/io/2009/sessions/BuildingScalableComplexApps.html


Robert

Jason C

unread,
Jul 21, 2010, 1:50:03 PM7/21/10
to Google App Engine
Weird, I was _just_ discussing this with a colleague at our office.

If you want a really hard check and are willing to pay some overhead
for it, AND you can't use the key_name approach that Robert suggests
which is the best solution, you can use a technique like this:
http://squeeville.com/2009/01/30/add-a-unique-constraint-to-google-app-engine/

We've typically used this for a User entity where we need a unique
email address, but we don't want to drive the email address into the
key_name because email addresses change.

j

Jeff Schwartz

unread,
Jul 21, 2010, 2:16:00 PM7/21/10
to google-a...@googlegroups.com
I'm catching this thread late but I'd create a model whose parent entity would be an instance of your service model. This new model would be sharded to reduce contention and it would contain a list of all the customer id's who are subscribed to the service.

You can reduce contention even more by assigning meaning to + and - and append these to the customer ids in the sharded intances' lists. Customer id + '+' would indicate subscribing to the service whereas Customer id + '-' would indicate their unsubscribing from the service. You can query on Cursomer id + '+' and Customer id + '-' and which ever has a greater count tells you if they are subscribed or unsubscribed and no results tell you that they never subscribed. This technique removes the need to update entries in the list which can be time consuming and contentious.

Just my $0.02

Jeff

--
You received this message because you are subscribed to the Google Groups "Google App Engine" group.
To post to this group, send email to google-a...@googlegroups.com.
To unsubscribe from this group, send email to google-appengi...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en.




--
--
Jeff
Reply all
Reply to author
Forward
0 new messages