Google application engine and python and objects that pass by value

This is indeed a python question, but it relates to a specific google app issue.

We have

class User (db.Model):
  email = db.StringProperty ()
  name = db.StringProperty ()
  password = db.StringProperty ()
  # more fields ..

Since the user account is done so often, we save a copy in the session using gaeutilities (as a bonus question, is this bad on GAE? I thought I would ease a bit.)

class UpdateProfile (webapp.RequestHandler):
  def post (self):
    # User posting update to his name
    self.session = sessions.Session ()

    #######
    # way # 1: update the copy of the User object in SESSION, then .put () it
    self.session ['current_user'] .name = self.request.get ('name')
    self.session ['current_user'] .put ()
    # does not work.
    #######

    #######
    # way # 2: make a copy of the User object in SESSION, then .put () it
    user = self.session ['current_user']
    user.name = self.request.get ('name')
    user.put ()
    # works to update the datastore, but the copy of user in self.session
    # is NOT UPDATED!  I thought Python was
    # pass-by-reference.   It is when you work with lists anyway.
    # Why isn't it "acting right" with this type of object ??
    #######


    #######
    # way # 3: way that works.
    user = self.session ['current_user']
    user.name = self.request.get ('name')
    user.put ()
    self.session ['current_user'] = user
    # works completely
    #######

What happens in each of these three cases? Why don't cases 1 and 2 work?

+2


source to share


3 answers


Sorry, I'm new to this site and I can't see where to comment on the answer?

Anyway, I fixed the specific issue that caused the original post. While data serialization is still suboptimal what happens on write, I was able to make sure that assigning model objects as items in a session would work as expected. Rather than rewrite serialization (would be a lot of correspondence), I decided instead to determine when the model was inserted as a session data item and set the ReferenceProperty on it. This means that model objects will never have to incur serialization overhead at all.



If the object associated with the ReferenceProperty is deleted, the ReferenceProperty in the session will be deleted when you try to load it. This means that you have to catch exceptions such as KeyError, which are raised by the Session like a dictionary. Hopefully this is intuitive enough, but I'm open to any comments. I will check this page several times over the next few weeks.

+1


source


I guess:

Putting objects in a session means the objects are serialized (usually pickled) and stored somewhere (disk, memory, db). When it is retrieved from the session, a new object is created from the serialized old state.



  • In the first example, each one self.session[ 'current_user' ]

    provides you with a new object, one of which you are updating and the other in the db.
  • In the second, you will get one object, save it in the DB, but not in the session.

Btw, Python is doing a "call by sharing", but that has nothing to do with your problem; -)

+3


source


I am the author of gaeutilities. I contacted Nick to talk about it and he gave me some good ideas. I will have a solution for this in the final version 1.3.

+2


source







All Articles