On Wednesday, July 4, 2012 1:59:49 AM UTC+2, mma wrote:
>
> Hi there.
>
> I get the following error only on production: BadRequestError: BLOB,
> ENITY_PROTO or TEXT properties must be in a raw_property field
>
> It happens when I put() a instance of the Receipt class (extends ndb.Model)
>
> Below, I attach the model and the handler where the code breaks (only in
> production)
>
>
> class Receipt(RModel):
> ownerId = ndb.IntegerProperty()
> houseId = ndb.IntegerProperty()
> renterId = ndb.IntegerProperty()
> year = ndb.IntegerProperty()
> month_number = ndb.IntegerProperty()
> code = ndb.StringProperty()
> description = ndb.StringProperty()
> value = ndb.StringProperty()
>
> owner = ndb.ComputedProperty(lambda self: Owner.get_by_id(self.ownerId))
> house = ndb.ComputedProperty(lambda self: House.get_by_id(self.houseId))
> renter = ndb.ComputedProperty(lambda self: Renter.get_by_id(self.renterId))
> month = ndb.ComputedProperty(lambda self:
> month_number_to_string(self.month_number))
>
These ComputedProperties look suspicious. The owner, house and renter
lambdas return entities; are you sure you don't mean to return their keys
instead? E.g. Owner.get_by_id(id) loads an Owner entity (which is a
blocking datastore call). If you just want to store the key, you can use
ndb.Key(Owner, id) instead.
If you really want to store these as entities, it's possible that you can
get away by declaring the ComputedProperty as indexed=False. But you're
probably better off declaring them as e.g. StructuredProperty(Owner), and
if you want them filled in automatically, you could do that in a pre-post
hook.
>
> class RModel(ndb.Model):
> created = ndb.DateTimeProperty(auto_now_add = True)
> changed = ndb.DateTimeProperty(auto_now_add = True)
> creatorId = ndb.IntegerProperty()
> changerId = ndb.IntegerProperty()
>
> #def to_dict(self):
> # return ndb.to_dict(self, {'id':self.key().id()})
>
Aside: What are you trying to do here? I think maybe you meant this:
def to_dict(self):
result = super(RModel, self).to_dict()
result['id'] = self.key.id()
return result
???
>
> def set_attributes(self, **attrs):
> props = self.properties()
> for prop in props.values():
> if prop.name in attrs:
> prop.__set__(self, attrs[prop.name])
>
Aside: this looks like code from old db. Its equivalent is
ent.populate(**attrs), except the latter complains if you specify a keyword
that has no corresponding property.
>
>
> class ReceiptNew(BaseHandler):
> def Get(self):
> user_id = self.get_user_id()
> owner = Owner.get_by_id(user_id)
> receipt = Receipt(value="")
> houses = list(House.gql("where ownerId = :1", owner.key.id()))
> renters = list(Renter.gql("where ownerId = :1", owner.key.id()))
> context = {'receipt': receipt, 'houses': houses, 'renters': renters,
> 'new': True}
> self.render_response('receipt-edit.html', **context)
>
> def post(self):
> user_id = self.get_user_id()
> owner = Owner.get_by_id(user_id)
>
> data = {
> 'year': self.request.get('year'),
> 'month': self.request.get('month'),
> 'house': self.request.get('house'),
> 'renter': self.request.get('renter'),
> 'value': self.request.get('value'),
> 'paid': self.request.get('paid')
> }
>
> receipt = Receipt()
> receipt.year = int(data.get('year'))
> receipt.month_number = int(data.get('month'))
> receipt.houseId = int(data.get('house'))
> receipt.renterId = int(data.get('renter'))
> receipt.value = data.get('value')
> receipt.ownerId = owner.key.id()
> receipt.put() # code breaks here, only in production
> self.redirect('/receipts')
>
>
--
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/-/iGh6NGBKo4wJ.
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.