Google App Engine Migrating from db to ndb datastore – creating a commenting system with webapp2 (part 1)

My previous post covered creating a commenting system using webapp2 with Jinja2 template. You can store comments into db model and render filtered comments using the key of a question. Click this link to see the post.

https://buzzcoding.com/2016/10/04/how-to-create-a-blog-comment-system-with-webapp2-on-google-app-engine-part-1/

This post is about creating the exact same commenting system except I will be using ndb model. The major difference here would be using the KeyProperty instead of the ReferenceProperty. Here’s the link to the side by side comparison chart of the two data models.

https://cloud.google.com/appengine/docs/python/ndb/db_to_ndb

Let’s start with importing the ndb data model.

from google.appengine.ext import ndb

First, change the db.Model to ndb.Model as well as each property. You can simply look at the comparison chart and change each property accordingly. Below code is my ndb model for Post and Reply entities.

class Post(ndb.Model):
    question = ndb.StringProperty(required = True)
    created = ndb.DateTimeProperty(auto_now_add = True)
    last_modified = ndb.DateTimeProperty(auto_now = True)

class Reply(ndb.Model):
    content = ndb.TextProperty(required = True)
    p_key= ndb.KeyProperty(kind=Post)
    created = ndb.DateTimeProperty(auto_now_add = True)
    last_modified = ndb.DateTimeProperty(auto_now = True)

The biggest change here would be the new KeyProperty which is the new version of our old ReferenceProperty. The concept has remained the same as you would need to store the key of a question to the property, p_key, in the Reply entity. This will allow us to fetch all the comments and simply filter by p_key to only render comments associated with a particular post.

Let’s look at how to store the key of a question to the Reply entity.

def post(self, post_id):
    reply_content = self.request.get('reply')
    p_key = ndb.Key('Post', int(post_id), parent=question_key())

    if reply_content:
        r = Reply(content=reply_content, p_key=p_key, user=user, user_key=u_key)
        r.put()

I was struggling for many hours as I was not able to store the key of a question into the Reply entity. Thus, I went on Stack Overflow for help. It turns out that I was trying to store a string that looks like a key instead of an actual key. Make sure that you are storing a key not a string!  Instead of getting the key of a post from the template, I simply created the key of the post in main.py by using the post_id that was passed through the url.  Here’s the link for more detailed explanation. Thanks to the great community of Stackoveflow.

http://stackoverflow.com/questions/39864359/google-app-engine-storing-key-into-ndb-keyproperty

The next post will cover rendering comments associated with a particular post.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s