Search code examples
pythongoogle-app-enginevideoapp-engine-ndbgoogle-app-engine-python

Video model and ndb


In appengine I deployed python code with this model for videos to be uploaded.

I enabled video uploads It appears instances of model "Video" in the datastore when a video is uploaded. I think the class should be used with ndb library instead of the legacy db-Model but i didn't learn ndb yet and my models are rather complicated and referenced.

class Video(db.Model):

  reference = db.ReferenceProperty(Item,
                                     collection_name='matched_videos', verbose_name='Title')
  content = blobstore.BlobReferenceProperty()
  title = db.StringProperty()
  filename = db.StringProperty()
  size = db.IntegerProperty()
  added = db.DateTimeProperty(verbose_name='added', auto_now_add=True)  # readonly

  def get_video(self,video_id):
    return Video.get_by_id(video_id)

Then when users upload videos I just check if the first upload is a video, otherwise it is plain images. I found that appengine could store ogv and mp4 but not all video formats. Storing an uploaded video looks like the following in my code.

 for upload in self.get_uploads():
        try:
            #logging.info(blobstore.blobstore.BlobInfo(upload.key()).content_type)

            content_type = blobstore.blobstore.BlobInfo(upload.key()).content_type

            if 'video' in content_type and not ad.hasvideo:
                vid = Video(reference=item)
                vid.content = upload.key()
                vid.title = blobstore.blobstore.BlobInfo(upload.key()).filename
                vid.size = blobstore.blobstore.BlobInfo(upload.key()).size

                tmp = upload.key()
                vid.put()
                item.hasvideo = True
                item.videos.append(upload.key())
            else:
                img = Image(reference=ad)
                img.primary_image = upload.key()

                img.put()
                item.hasimages = True
                item.image_url = images.get_serving_url(str(upload.key()), size=640)

                item.blobs.append(upload.key())

                item.put()
            counter = counter + 1
        except Exception, e:
            logging.error('There was an exception:%s' % str(e.message))
            pass

Then viewing a video I use this code.

class ViewVideo(BaseRequestHandler,blobstore_handlers.BlobstoreDownloadHandler):

  def get_video_content(self,content):
    query_str = "SELECT * FROM Video WHERE content =:content"
    return db.GqlQuery(query_str,content=content).get()

  def get(self):


    video_id = self.request.get('video_id')
    video_instance = None
    if video_id:
        video_instance = self.get_video_content(video_id)



        self.response.headers['Content-Type'] = blobstore.blobstore.BlobInfo(video_instance.content.key()).content_type

        self.send_blob(video_instance.content.key())

The model item is a class for an item that is posted by a user. Now my question if if I should rewrite it to use ndb datastore instead? I started this project before ndb existed and I realize that it seems better to use ndb but if my Item class is also not ndb, can I make references between mndb models and non-ndb models or must I migrate all models at the same time?


Solution

  • 1) Stop using blobstore, and put your videos in a GCS (Google Cloud Storage) bucket.

    2) Store the key to the GCD video in your ndb model. The other properties are easy to switch over to ndb.