By the way, theres a wiki page on Udacity about NDB vs DB:
http://forums.udacity.com/cs253/questions/30012/gae-db-vs-ndb?page=1&focusedAnswerId=30058#30058

On Friday, July 6, 2012 12:16:31 AM UTC+1, mma wrote:
>
> 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/-/s5mG6flZNJUJ.
To post to this group, send email to google-appengine@googlegroups.com.
To unsubscribe from this group, send email to 
google-appengine+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/google-appengine?hl=en.

Reply via email to