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.

Reply via email to