Guido, thanks for taking the time to respond.
You're right on ComputedProperty. I used it the wrong way. See more about
that:
http://stackoverflow.com/questions/11324435/ndb-badrequesterror-only-in-production/11324606#comment14917060_11324606
You're right also on the "asides". I'm not using that part and will remove
it from the code.
PS: As you might have guessed, I'm a newbie on Python and on App Engine
Python. First contact was thru Udacity's CS 101 and CS 253 (web apps). I
get things to work, but some part of the code is not professional. I do
unit testing, though -- learned it by watching Misko Hevery videos.
On Thursday, July 5, 2012 10:46:00 AM UTC+1, Guido van Rossum wrote:
>
> 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/-/Pv_a6LOZg_wJ.
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.