no probl.
To elaborate this further for others having the same issue....

People (programmers, often) tend to forget that db engines are programs. 
They have their own algorithms too (and they take time). 
It's true that they have pretty rock-solid algos and do their work very 
fast, but having python filtering rows objects sometimes is even faster 
than specifying some super-duper "where" filters in the query itself. 
When the "super-duper" where is going to cut out the 90% of 10000 rows 
returned it can be safer to look into the database algos, but if you're 
going to fetch a (relatively small) set and cut it out (with filter() or 
search()) by the 20%, it's generally a good advice to do that in plain 
python.
As a general "rule of thumb", condition based on a function like yours (the 
db should have been forced to calculate the date whose difference is now - 
the number of days in another column, always variable) is the best scenario 
where this kind of things is high valuable, i.e. probably faster in python 
than the db (assuming that you're able to write that in plain T-SQL).

I actually had this kind of problem and (I'm a professional db developer 
and not a python programmer) tried to write a super-optimized query (was a 
scoring system based on pretty complicated combined averages).

When I implemented the same logic in plain python, other than being far 
more readable and maintainable, I cut off execution times from ~25 min to 
~47 sec.

On Thursday, July 26, 2012 6:03:24 PM UTC+2, jw wrote:
>
> cards2learn.exclude(lambda row: row.userCard.lastTimeLearned > date.today
> () - timedelta(days=row.userCard.stage))   
>
> Niphlod, you made my day!! Thank you so much! And thank you all for the 
> advices!
>
>
> On Thursday, July 26, 2012 5:52:29 PM UTC+2, Niphlod wrote:
>>
>> Currently you'd have to code a view in the database (or simply a "string" 
>> condition to pass on) to achieve that. 
>>
>> date.today() - timedelta(something) is a python "fixed" value that 
>> doesn't get re-evaluated at runtime by the database substituting the 
>> "something" for each value of every row.
>>
>> If you need the structure to be portable and absolutely need to have a 
>> single query fetching all of this, you need to change your db structure.
>>
>> If you're going to run always on a "fixed" db engine you could write 
>> something exploiting the functionalities of that db engine.
>>
>> Remember that most of the times is easier (and the resources negligible) 
>> to fetch rows from the db and filter them with python.
>>
>> cards2learn = db((db.groupCards.card_id == db.card.id) \
>>         & (db.groupCards.studyGroup_id == auth.user.studyGroup_id) \
>>         & (session.chosenSubject_id == db.card.subject_id) \
>>         & (db.userCard.card_id == db.card.id)
>>         & (db.userCard.stage <= 5) \
>>         #& (db.userCard.lastTimeLearned < (date.today() - 
>> timedelta(days=(1))))
>>         ).select(db.userCard.ALL,db.card.ALL,db.groupCards.ALL, left=db.
>> userCard.on((db.userCard.card_id == db.card.id)))
>>
>> cards2learn.exclude(lambda row: row.usercard.lasttimelearned < request.now 
>> - timedelta(days=row.usercard.stage))
>>
>>
>>
>>
>>
>>  should work. (totally untested)
>>
>> On Thursday, July 26, 2012 5:23:51 PM UTC+2, jw wrote:
>>>
>>> Ok guys... I did step for step and now the query works for the stage 
>>> (progress).
>>> The second thing (stage is multiplicator for time) I have no glue how to 
>>> move on.
>>>
>>> cards2learn = db((db.groupCards.card_id == db.card.id) \
>>>         & (db.groupCards.studyGroup_id == auth.user.studyGroup_id) \
>>>         & (session.chosenSubject_id == db.card.subject_id) \
>>>         & (db.userCard.card_id == db.card.id)
>>>         & (db.userCard.stage <= 5) \
>>>         & (db.userCard.lastTimeLearned < (date.today() - 
>>> timedelta(days=(1))))
>>>         ).select(db.userCard.ALL,db.card.ALL,db.groupCards.ALL, 
>>> left=db.userCard.on((db.userCard.card_id == db.card.id)))
>>>
>>> timedelta(days=(1)) should be timedelta(days=(db.userCard.stage)) but it 
>>> says:
>>> <type 'exceptions.TypeError'> unsupported type for timedelta days 
>>> component: Field
>>> How do I use the db.userCard.stage in timedelta (stage is an integer 
>>> field in the table)?
>>>
>>> Many thanks for the previous answers!
>>>
>>

-- 



Reply via email to