2

Trying to make most of the GAE Datastore entities concept, but some doubts drill my head.

Say I have the model:

class User(ndb.Model):
    email = ndb.StringProperty(indexed=True)
    password = ndb.StringProperty(indexed=False)
    first_name = ndb.StringProperty(indexed=False)
    last_name = ndb.StringProperty(indexed=False)
    created_at = ndb.DateTimeProperty(auto_now_add=True)

    @classmethod
    def key(cls, email):
        return ndb.Key(User, email)

    @classmethod
    def Add(cls, email, password, first_name, last_name):
        user = User(parent=cls.key(email),
                    email=email,
                    password=password,
                    first_name=first_name,
                    last_name=last_name)
        user.put()
        UserLogin.Record(email)


class UserLogin(ndb.Model):
    time = ndb.DateTimeProperty(auto_now_add=True)

    @classmethod
    def Record(cls, user_email):
        login = UserLogin(parent=User.key(user_email))
        login.put()

And I need to keep track of times of successful login operations. Each time user logs in, an UserLogin.Record() method will be executed. Now the question — do I make it right?

Thanks.


EDIT 2

Ok, used the typed arguments, but then it raised this: Expected Key instance, got User(key=Key('User', 5418393301680128), created_at=datetime.datetime(2013, 6, 27, 10, 12, 25, 479928), email=u'al@mail.com', first_name=u'First', last_name=u'Last', password=u'password'). It's clear to understand, but I don't get why the docs are misleading? They implicitly propose to use:

# Set Employee as Address entity's parent directly...
address = Address(parent=employee)

But Model expects key. And what's worse the parent=user.key() swears that key() isn't callable. And I found out the user.key works.


EDIT 1

After reading the example form the docs and trying to replicate it — I got type error: TypeError('Model constructor takes no positional arguments.'). This is the exacto code used:

user = User('al@mail.com', 'password', 'First', 'Last')
user.put()

stamp = UserLogin(parent=user)
stamp.put()

I understand that Model was given the wrong argument, BUT why it's in the docs?

1 Answer 1

1

Yes, this method of recording logins should work. I would think about whether you truly need to store login records in the database, though. The other way to do it is to write logins to your log, like this:

logging.info("User %s logged in" % user.email)

You need to use named arguments instead of positional arguments when initializing any Model subclass. Instead of this:

user = User('al@mail.com', 'password', 'First', 'Last')

just create your user like this:

user = User(email='al@mail.com', password='password', first_name='First', last_name='Last')

And it does seem like you uncovered an issue with the documentation regarding Address(parent=employee). Just use the key, I suppose. Good catch.

By the way, App Engine's official support forum is Stack Overflow, so it's better to post questions there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.