I don't think this has anything to do with the previous thread that had the
same subject.
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
>>>
--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/-/a1oGk6uYnNMJ.
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.