On Monday, October 8, 2012 1:28:57 PM UTC-7, Guido van Rossum wrote:

> I don't think this has anything to do with the previous thread that had 
> the same subject.


Apologies, I think you had the same issue, you just got there a different 
way.
 

> The problem must be that your ComputedProperty is trying returning a Model 
> instance. That's unfortunately not supported; ComputedProperty as it is 
> currently implemented can only support the "basic" data types like int, str 
> and the like. I'm not sure why this doesn't trigger an error in the dev 
> appserver for you -- when I try something similar it does trigger the error 
> in a test.(*) I'm also not sure what's the best solution; you may just have 
> to break up the computed structured property up into two separate computed 
> property.
>
> (*) My session log:
>
> >>> class A(Model):
> ...  x = IntegerProperty()
> ... 
> >>> class M(Model):
> ...  a = ComputedProperty(lambda self: A(x=1))
> ... 
> >>> m = M()
> >>> m.a
> A(x=1)
> >>> m.put()
> WARNING:root:suspended generator _put_tasklet(context.py:274) raised 
> BadRequestError(BLOB, ENITY_PROTO or TEXT property a must be in a 
> raw_property field)
> WARNING:root:suspended generator put(context.py:703) raised 
> BadRequestError(BLOB, ENITY_PROTO or TEXT property a must be in a 
> raw_property field)
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "/Users/guido/appengine-ndb-experiment/ndb/model.py", line 3151, in 
> _put
>     return self._put_async(**ctx_options).get_result()
>   File "/Users/guido/appengine-ndb-experiment/ndb/tasklets.py", line 325, 
> in get_result
>     self.check_success()
>   File "/Users/guido/appengine-ndb-experiment/ndb/tasklets.py", line 368, 
> in _help_tasklet_along
>     value = gen.throw(exc.__class__, exc, tb)
>   File "/Users/guido/appengine-ndb-experiment/ndb/context.py", line 703, 
> in put
>     key = yield self._put_batcher.add(entity, options)
>   File "/Users/guido/appengine-ndb-experiment/ndb/tasklets.py", line 368, 
> in _help_tasklet_along
>     value = gen.throw(exc.__class__, exc, tb)
>   File "/Users/guido/appengine-ndb-experiment/ndb/context.py", line 274, 
> in _put_tasklet
>     keys = yield self._conn.async_put(options, datastore_entities)
>   File "/Users/guido/appengine-ndb-experiment/ndb/tasklets.py", line 454, 
> in _on_rpc_completion
>     result = rpc.get_result()
>   File 
> "/usr/local/google_appengine/google/appengine/api/apiproxy_stub_map.py", 
> line 604, in get_result
>     return self.__get_result_hook(self)
>   File 
> "/usr/local/google_appengine/google/appengine/datastore/datastore_rpc.py", 
> line 1569, in __put_hook
>     self.check_rpc_success(rpc)
>   File 
> "/usr/local/google_appengine/google/appengine/datastore/datastore_rpc.py", 
> line 1224, in check_rpc_success
>     raise _ToDatastoreError(err)
> google.appengine.api.datastore_errors.BadRequestError: BLOB, ENITY_PROTO 
> or TEXT property a must be in a raw_property field
> >>> 
>

Further experimentation suggests that making the ComputedEntity 
indexed=False will make this (seem to) work. However it will behave more 
like a LocalStructuredProperty than a StructuredProperty -- the Account 
entity is serialized as a single bytestring, not stored as two separate 
properties with a dot in their names like the StructuredProperty(Account) 
properties are. I'm not sure if you're happy with that or not.
 

>
> --Guido
>
> On Monday, October 8, 2012 9:40:49 AM UTC-7, Primijos wrote:
>>
>> Hi,
>>
>> I'm getting also this error trying to put() [to be exact, trying to do a 
>> get_or_insert] an entity with a computed property. My Model looks more or 
>> less like this (removed non-relevant code):
>>
>> class DecimalProperty(ndb.StringProperty):
>>    def _validate(self,value):
>>       if not isinstance(value,(int,long,basestring,decimal.Decimal)):
>>          raise ndb.BadValueError("Property %s must be a decimal, string, 
>> float or int." % self.name)
>>       return decimal.Decimal(value).quantize(TWOPLACES)
>>
>>    def _to_base_type(self,value):
>>       if value>=0:
>>          return "P%010d" % (value*100)
>>       else:
>>          new_value = MAX_DECIMAL + (value*100)
>>          return "N%010d" % new_value
>>
>>
>>    def _from_base_type(self,value):
>>       if value[0] == "P":
>>          return (decimal.Decimal(value[1:])/100).quantize(TWOPLACES)
>>       else:
>>          tmp = decimal.Decimal(value[1:])
>>          tmp = - (MAX_DECIMAL - tmp)
>>          return (decimal.Decimal(tmp)/100).quantize(TWOPLACES)
>>
>>
>> class Accounting(ndb.Model):
>>    expense           = DecimalProperty(required=False,indexed=False,
>> default=DEC_ZERO)
>>    investment        = DecimalProperty(required=False,indexed=False,
>> default=DEC_ZERO)
>>
>>
>> def accountable_basic_compute_balance(accountable):
>>    expense = accountable.commited.expense - accountable.invoiced.expense
>>    investment = accountable.invoiced.investment - accountable.invoiced.
>> investment
>>    return Accounting(expense = expense, investment = investment)
>>
>>
>> class AccountableBasic(ndb.Model):
>>    def __init__(self, *args, **kwargs):
>>       # initialize structure
>>       super(AccountableBasic, self).__init__(*args, **kwargs)
>>       self.commited = Accounting()
>>       self.invoiced = Accounting()
>>
>>    commited = ndb.StructuredProperty(Accounting, repeated = False,indexed
>> =True)
>>    invoiced = ndb.StructuredProperty(Accounting, repeated = False,indexed
>> =True)
>>    balance  = 
>> ndb.ComputedProperty(accountable_basic_compute_balance,repeated 
>> = False, indexed=True)
>>
>>
>> class YearAccounting(AccountableBasic):
>>    # id (key_name) = year
>>    pass
>>
>> Everything works fine in the local dev server, when I try to perform a 
>> YearAccounting.get_or_insert in production, I get the following error:
>>
>> BadRequestError: BLOB, ENITY_PROTO or TEXT properties must be in a 
>> raw_property field
>>
>>
>> I'm assuming that's related to the "balance" property in YearAccouting 
>> (subclass of AccountableBasic) , which in dev shows as follows in the 
>> datastore viewer:
>>
>> balance (entity:proto)
>> <binary>
>>
>> I had some problems previously in production trying to use a 
>> ComputedProperty that returned a DecimalProperty (basically, a "total" 
>> property: a ComputedProperty that returened a DecimalProperty): dev app 
>> server complained about it, so I've removed it, however it seemed to be 
>> happy with a ComputedProperty that returned a Accounting instance, but the 
>> production runtime doen't look so happy with it...
>>
>> Any help will be welcome.
>>
>> thanks in advance,
>> Jose
>>
>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"Google App Engine" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/google-appengine/-/h4NDp_g5KMYJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-appengine?hl=en.

Reply via email to