Reputation: 32071
I have a User entity in my Google App Engine model, and a user has a name, email, password, and some other stuff. Currently, I use the user's email as the key to the entity. Up until now, I hadn't considered what would happen if the user were to change his email.
The reason using email as the key was so convenient is that the client device always knows the users email, and rather than storing and keeping track of some separate user_id, it would be more convenient to just look up by email.
So what if the user does change their email? Is it a big deal after all - is the work to be done trivial? What are some better options for keys for a user?
Upvotes: 0
Views: 150
Reputation: 123
Using the federated identity option on App Engine I've gone for an approach of having a primary_federated_identity as the key for each user. That way users can change email, handle, anything else but still be the same person.
Like @Tim Hoffman, as well as the primary_federated_identity I use a child entity but in my case it's a UserIdentity collection.
class User(db.Model):
primary_federated_identity = db.StringProperty(required = True)
handle = db.StringProperty(required = True)
created = db.DateTimeProperty(required = True, auto_now_add = True)
...
class UserIdentity(db.Model):
user = db.ReferenceProperty(User, collection_name = 'user_identities')
user_federated_identity = db.StringProperty(required = True)
user_federated_provider = db.StringProperty(required = True)
...
When I write a new user:
from google.appengine.api import users
from models.models import User
...
def some_function():
key_name = users.federated_identity()
my_site_user = User(key_name = key_name, primary_federated_identity=key_name, handle=handle)
And when I retrieve one:
key_name = user.federated_identity()
return User.get_by_key_name(key_name)
Upvotes: 2
Reputation: 12986
In a project I designed we have the login & hashed password plus other properties (enabled flag, password change flag etc) kept as a separate child entity of the user. The key of this entity was the login. This meant that the key (login) could be changed at any time, and we could remove/replace the child entity with out having to rekey things etc..... It did mean an ancestor query is required to get the user, but then this was cached (memcache etc) after the first retrieval.
This approach keeps all the login details out of the user, (we actually supported google logins as well as authtkt userid/passwd style logins, by changing the implementation of the child auth entity.)
Upvotes: 0
Reputation: 31928
if email == key then when a user wants to change his email you will need to create a new user entity.
Usually emails are not a good key for that reason, you can have a system that will replace all the old reference into new ones but that depends on how complicated is your system.
Upvotes: 0
Reputation: 3284
Use an int/Integer and GAE will assign a key value for you.
Upvotes: 1