Search code examples
google-app-enginegoogle-cloud-datastoreblobstore

Best way to link datastore entity to its blobstore image?


Let's say I have a model for my email address book:

class contact(db.Model):
    email = db.EmailProperty()
    image = #Hmm.

My contacts' images will be stored in the Blobstore, and served at various sizes.

So, should I use a db.ReferenceProperty(BlobInfo) such that I can serve it by doing:

get_serving_url(alice.image.key, size=x)

Or should I use a db.StringProperty so that I don't have to make the second read in order to get the key:

get_serving_url(alice.image, size=x)

Or should I use a db.LinkProperty for the base URL, post-fixing the size needed:

alice.image+'=sx'

I don't foresee needing anything other than the key, so I think the second is better than the first.

Though I am unsure if the third is best because I am unsure whether it is as efficient as creating a unique URL, which can be cached to avoid repeatedly generating the same thumbnail - or is this handled automagically in both cases?


Solution

  • After some experimentation, I think I can answer my own question.

    Well, sort of. It turns out that the answer is "this wasn't a real problem to begin with".

    While get_serving_url() gives the impression that something fancy is being done, actually the 'serving URL' is nothing more than a post-fixing of the supplied BlobKey.

    What's more, supplying size=x merely appends =sx - there's nothing special, more or less efficient, about doing it this way. My second and third options, really are identical.

    Finally, the __BlobInfo__ entity kind uses the BlobKey as its key name, so it is also easy to access from the other.


    I have decided to use, and would suggest to anyone with the same dilemma, my third option:

    imgBlob = db.LinkProperty()
    

    It is then easy to:

    • append any resizing/cropping requirements
    • give a default value/make required without overloading put()