GoogleCloudPlatform / datastore-ndb-python

Client library for use with Google Cloud Datastore from within the Google App Engine Python runtime.
https://cloud.google.com/appengine/docs/standard/python/ndb/
Apache License 2.0
114 stars 48 forks source link

NDB structuredProperty randomly converting actual value. #283

Open protodmorgan opened 6 years ago

protodmorgan commented 6 years ago

I'm working with a nested json I'm converted into NDB models that are structured. However, the last line of my attempt to contructed the model randomly converts the actual value. I might just be doing something wrong, but I asked on stackoverflow and haven't seen a response. I'm calling a bug at this point due to my testing.

data being passed in..

Models:

class SensorConfig(ndb.Model):
    type = ndb.StringProperty()
    label = ndb.StringProperty()
    description = ndb.StringProperty()
    lowerRange = ndb.IntegerProperty()
    upperRange = ndb.IntegerProperty()

class Algorithm(ndb.Model):
    name = ndb.StringProperty()
    version = ndb.StringProperty()
    setpoint = ndb.IntegerProperty()
    setpointUnits = ndb.StringProperty()

class Setting(ndb.Model):
    action = ndb.StringProperty()
    name = ndb.StringProperty()
    title = ndb.StringProperty()
    product = ndb.StringProperty()
    productType = ndb.StringProperty()
    productBrand = ndb.StringProperty()
    productKeywords = ndb.StringProperty()
    level = ndb.IntegerProperty()
    mode = ndb.StringProperty()
    algorithm = ndb.StructuredProperty(Algorithm)
    htpGen = ndb.StringProperty()
    firmwareVersion = ndb.StringProperty()
    sensorConfig = ndb.LocalStructuredProperty(SensorConfig, repeated=True)

class DirectionModel(ndb.Model):
    created_at = ndb.DateTimeProperty(auto_now_add=True)
    deviceId = ndb.StringProperty()
    deviceName = ndb.StringProperty()
    updated_at = ndb.DateTimeProperty(auto_now=True)
    settings = ndb.StructuredProperty(Setting)
    keywords = ndb.StringProperty(repeated=True)Models: 
settings = json.loads(request.settings)
        keywords = settings['productKeywords']
        print type(settings) *shows at dict*
        print keywords
        print int(settings['sensorConfig'][1]['upperRange']), type(int(settings['sensorConfig'][1]['upperRange'])) *shows as 400 and Int*
        convert = settings['sensorConfig'][1]['upperRange']
        print convert, type(convert)   *Shows as 400 type unicode*
        converted = int(convert) 
        print converted, type(converted)   *Shows as 400 type Int* 
        test = DirectionModel(namespace='cookingDirections',
                              deviceId=request.deviceId,
                              deviceName=request.deviceName,
                              settings=Setting(action=settings['action'], name=settings['name'],
                                               title=settings['title'], productType=settings['productType'],
                                               productBrand=settings['productBrand'],
                                               productKeywords=settings['productKeywords'], level=settings['level'],
                                               mode=settings['mode'],
                                               keywords=keywords.split(','),
                                               algorithm=Algorithm(name=settings['algorithm']['name'],
                                                                   version=settings['algorithm']['version'],
                                                                   setpoint=int(settings['algorithm']['setpoint']),
                                                                   setpointUnits=settings['algorithm']['setpointUnits']),
                                               htpGen=settings['htpGen'],
                                               firmwareVersion=settings['firmwareVersion'],
                                               sensorConfig=[
                                            SensorConfig(
                                                type=settings['sensorConfig'][0]['type'],
                                                label=settings['sensorConfig'][0]['label'],
                                                description=settings['sensorConfig'][0]['description'],
                                                lowerRange=int(settings['sensorConfig'][0]['lowerRange']),
                                                upperRange=int(settings['sensorConfig'][0]['upperRange'])),
                                            SensorConfig(
                                                type=settings['sensorConfig'][1]['type'],
                                                label=settings['sensorConfig'][1]['label'],
                                                description=settings['sensorConfig'][1]['description'],
                                                lowerRange=int(settings['sensorConfig'][1]['lowerRange']),
                                                upperRange=converted,   *ERROR HERE*
                                            )]))

So, last line where upperRange=converted No matter how i pass in the value. App engine throws back an error BadValue got u'5' expect Int. Even tho above shows the value is actually 400 and is INT.

IF I just pass in settings['sensorConfig'][1]['upperRange'] with out conversion. I get an error that I expect which is Type Error Unicode "400". So basically if I'm not converting the value type...it see it correctly. If I change the IntergerProperty to StringProperty I see u'5' again. If I hard code a value instead of passing in a variable I still see it try passing in u'5'. If I'm doing something wrong I'm at a lost on what.

tmst commented 6 years ago

Presumably you've seen #228.

protodmorgan commented 6 years ago

I have, but seems to happen even if I switch to LocalStructuredProperties as well.