On Thursday 16 November 2017 07:21:38 Josh Smeaton wrote:
>
> I don't agree with reimplementing lookups/transforms/funcs to produce the
> python version of a SQL concept. It's a leaky abstraction. Instead, I'd
> prefer the model author provides their python calculation:
>
> is_adult = models.CalculatedField(Q(age__gte=18), lambda c: c.age >= 18)
(name shortened to fit in a 80-char line)
I disagree. The way I see it, these calculated fields should essentially
provide a declarative way to add an annotate() that's always going to be
there. There should be only one source of truth, and that's the database;
parallel implementations tend to disagree on fringe cases with disappointing
results (e.g. consider if age above is nullable -- the database then makes the
calculated field null, the python above makes it raise an exception). Or
consider calculated fields which are aggregates -- a Python version could very
easily become painfully inefficient.
>
> There may be destructuring/serialisation issues (migrations/pickle) using
> lambda, unless we can ignore these model fields during deserialisation.
>
That's another (though minor) argument against lambdas here.
No, the way I see it, the API should just use expressions. Of note, I think it
should also support the output_field keyword. At the hand-waving, brainstorming
level, I think we might, at some point, actually try to implement this by
creating objects in the database (views on Postgres, computed columns on
MySql, etc) -- so that the field is really available in all contexts.
My 2 cents,
Shai.