Problem solved. My mistake was in thinking that the 'r' in the lambda 
function referred to the C record. Of course it doesn't; we're trying to 
INSERT a new C record. Instead, that 'r' refers to the parent B record. So 
the lambda function should be:

lambda r : '%s' % (db.A[r.A_id].A_name) 

On Wednesday, July 11, 2012 9:54:24 AM UTC-6, MichaelF wrote:
>
> Okay; I understand. Let me explain using a simpler version, and also come 
> up with SQL that would do the equivalent.
>
> Here's a simpler version. This example shows the problem, and simply uses 
> a grandparent table (A), a parent table (B), and a child table (C). That 
> is, C is a child of B, and B is a child of A:
>
> db.define_table('A',
>                 Field('A_name', 'string', required=True),
>                 format='%(A_name)s')
>
> db.define_table('B',
>                 Field('A_id', db.A),
>                 Field('B_name', 'string', required=True),
>                 format='%(B_name)s')
>
> db.define_table('C',
>                 Field('B_id', db.B),
>                 Field('C_name', 'string', required=True),
>                 format='%(C_name)s')
> db.C.B_id.requires=IS_IN_DB(db, 'B.id',
>       lambda r : '%s' % (db.A[db.B[r.B_id].A_id].A_name)
>       )
>
> If I leave the lambda out, then the drop-down values are B.id values. I 
> can make that be B.B_name values easily, but what I want are A.A_name 
> values. The lambda is fairly straightforward (although I'm obviously 
> missing something).
>
>       lambda r : '%s' % (db.A[db.B[r.B_id].A_id].A_name)
>
> The 'r' is the current record, and we're looking at a C record, so it first 
> evaluates r.B_id, B_id being the foreign key in the C record of its 
> parent B record. Let's say this evaluates to 123 (for example), which would 
> then be id 123 in the B table. Now, replacing r.B_id with 123 we get:
>
>       lambda r : '%s' % (db.A[db.B[123].A_id].A_name)
>
> So now it evaluates db.B[123].A_id, A_id being the foreign key in the B 
> record of its parent A record:
>
>       lambda r : '%s' % (db.A[db.B[123].A_id].A_name)
>
> Let's say that evaluates to 456, which would then be id 456 in the A 
> table. Replacing db.B[123].A_id with 456 we get:
>
>       lambda r : '%s' % (db.A[456].A_name)
>
> So now it evaluates db.A[456].A_name, which is what I'd like to see in the 
> drop-down. And yet the error I get is:
> <type 'exceptions.KeyError'> 'B_id'
>
> An equivalent SQL to get the A_name for each C id would be:
>
> SELECT C.id, A.A_name
> FROM A                  INNER JOIN
>      B ON A.id = B.A_id INNER JOIN
>      C ON B.id = C.B_id;
>
> Thoughts?
>
> Thanks.
>
> On Wednesday, July 11, 2012 3:24:41 AM UTC-6, Johann Spies wrote:
>>
>> On 11 July 2012 05:27, MichaelF <[email protected]> wrote:
>>
>>> Didn't help. I now get the same error, this time in the function. Any 
>>> idea what the error message is trying to tell me?
>>
>>
>> Unfortunately I don't have time to try and work out your logic.  The 
>> error is telling you that the process could not find the key C1_2 in your 
>> database query.  You have some logical proglem in your code.
>>
>> Try and build an SQL-query to which you can translate into a function.
>>
>> Regards
>> Johann
>>  
>> -- 
>> Because experiencing your loyal love is better than life itself, 
>> my lips will praise you.  (Psalm 63:3)
>>
>>

Reply via email to