John Allard
John Allard

Reputation: 3894

Google Cloud Datastore Python Library - force entity property to TextProperty instead of bytes?

I'm using the Google cloud datastore library for python, the one that you get by doing from google.cloud import datastore (sorry I can't be more specific, I know there are like 3 or 4 different libraries including ndb). The issue is that when I'm trying to save a TextProperty it ends up being a BytesProperty as base64 encoded data. Code below

    from google.cloud import datastore
    expiration_date = plan.get('expiration_date')
    ds = datastore.Client()
    dt = datetime.datetime.utcnow()
    key_str= "%s:%s:%s" % (user_id, camera_id, dt.isoformat())
    complete_key = ds.key('RollingPlanCounter', key_str)
    rolling_counter = datastore.Entity(key=complete_key, exclude_from_indexes=['byte_counts'])
    byte_counts = json.dumps({
        'upload_bytes_total': 0,
        'movie_bytes_total': 0,
        'event_bytes_total': 0,
        'upload_bytes_total_important': 0,
        'movie_bytes_total_important': 0,
        'event_bytes_total_important': 0
    })
    rolling_counter.update({
        "user_id": user_id,
        "camera_id": camera_id,
        "creation_date": dt,
        "expiration_date": expiration_date,
        "byte_counts": str(byte_counts)
    })

But when I look in datastore I see this

base64 data

How do I have a 'hint' to the library that this should be a TextProperty and not a Bytes?

Upvotes: 0

Views: 382

Answers (1)

John Allard
John Allard

Reputation: 3894

According to this page (https://googlecloudplatform.github.io/google-cloud-python/latest/datastore/usage.html#module-google.cloud.datastore), specifically this part

Note Property values which are “text” (‘unicode’ in Python2, ‘str’ in Python3) map to ‘string_value’ in the datastore; values which are “bytes” (‘str’ in Python2, ‘bytes’ in Python3) map to ‘blob_value’.

You need to cast to cast to unicode for it to know to have it be a TextProperty. So all I had to do was this

    byte_counts = json.dumps({
        'upload_bytes_total': 0,
        'movie_bytes_total': 0,
        'event_bytes_total': 0,
        'upload_bytes_total_important': 0,
        'movie_bytes_total_important': 0,
        'event_bytes_total_important': 0
        'events_important_count': 0,
        'movies_important_count': 0
        'movies_discarded_count': 0
    })
    rolling_counter.update({
        "user_id": user_id,
        "camera_id": camera_id,
        "creation_date": dt,
        "expiration_date": expiration_date,
        "byte_counts": unicode(byte_counts, "utf-8") # <-- here
    })

and the datastore now shows that they're being stored as text property.

Upvotes: 1

Related Questions