Sure. I was planning to work on it myself, but wanted to discuss API, 
passing in output_fields, and casting results first.
I started with 2 classes because I only needed SimpleCase first to 
implement the bulk_update. Later I added Case and it seemed clearer to me 
than the SQLAlchemy and PeeWee approach of using an optional predicate 
argument.

- Michael

On Tuesday, December 16, 2014 5:54:05 AM UTC+1, Josh Smeaton wrote:

> Hi Michal,
>
> I'm about ready to implement Case/When expressions, do you mind if I use 
> your implementation? Also, do you think it's necessary or desirable to have 
> a SimpleCase and a Case?
>
> Josh
>
> On Wednesday, 19 November 2014 08:34:10 UTC+11, Michał Modzelewski wrote:
>>
>> I've put my code up on github at 
>> https://github.com/michalmo/django-case-expressions. I've decided not to 
>> create a Django branch yet as I'd like to decide on some API issues first.
>>
>> Josh noted that I could avoid asking the user to set an output_field by 
>> doing it automatically in resolve_expression, but I'm not sure how to go 
>> about this. In the bulk_update case I can get the field from the model. 
>> When a Case is used in an update and SQLUpdateCompiler.as_sql calls 
>> resolve_expression I could look for self in query.values, but what if a 
>> single instance has been used more than once? I think it would be best if 
>> resolve_expression took an extra field parameter which could be used by 
>> SQLUpdateCompiler to pass the update field in to ExpressionNodes, and by 
>> ExpressionNodes to pass their output_field down to child 
>> nodes. Otherwise an extra method for passing in the output_field. 
>> Unless, of course, there's something I've overlooked.
>>
>> bulk_merge could also just split objects into groups with and without a 
>> set pk, and call bulk_create and bulk_update with those groups. I think 
>> bulk_save would be more inline with existing method names, though, or 
>> bulk_update_or_create.
>>
>> As far as API goes SQLAlchemy uses 
>> <http://docs.sqlalchemy.org/en/rel_0_7/core/expression_api.html#sqlalchemy.sql.expression.case>
>>  case(whens, 
>> value, else_) where whens is a list of tuples, value is the predicate 
>> expression and turns the case into a simple case expressions if set, 
>> else_ is the value for the ELSE clause. PeeWee uses 
>> <https://peewee.readthedocs.org/en/latest/peewee/playhouse.html#case> 
>> case(predicate, expression_tuples, default) where predicate is the 
>> predicate expression for a simple case expression, and creates a searched 
>> case expression if it is set to None.
>>
>> I favoured two expression classes so each could be responsible for 
>> validating arguments, eq. Case requires conditions to be Q objects.
>>
>> I also tried to use a dictionary mapping conditions to values, which 
>> seemed more readable, but that requires using OrderedDict if the user 
>> cared about the order of WHEN clauses in the generated SQL. Since 
>> constructing an OrderedDict requires passing in a list of tuples anyway I 
>> decided against using a dictionary. I assume this is what motivated the API 
>> in SQLAlchemy and PeeWee.
>>
>> - Michael
>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/13227bd1-54b1-49ba-8d35-f9d61e0c7d6c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to