4 ms·
I'm okay with ORMs, but I can't stand lazy evaluation. It often leads to situations where it's entirely unclear when the program is making a database call. Fo
by speedplane 7y ago
I'm okay with ORMs, but I can't stand lazy evaluation. It often leads to situations where it's entirely unclear when the program is making a database call.
For example, given the small django program:
dbcall = models.Purchases.objects.filter(amount = 100)
if dbcall:
do_something()
if len(dbcall) > 5:
do_something_else()
third_thing(dbcall[0])
Does the above app make 1, 2 or 3 database requests? There is an answer, but it's not at all clear to the developer.
- Nicksil 7y ago>There is an answer, but it's not at all clear to the developer. A cursory reading of the documentation is usually a first step in acclimating to an otherwise unfamiliar system. It just so happens, for your example here, a complete explanation[1] can be found at the very top of what's likely the most vital subsystem's documentation. During due diligence, this information will be among the first encounters. [1]https://docs.djangoproject.com/en/stable/ref/models/querysets/#when-querysets-are-evaluated https://docs.djangoproject.com/en/stable/ref/models/queryset...
- speedplane 7y ago> A cursory reading of the [django] documentation is usually a first step in acclimating to an otherwise unfamiliar system. It just so happens, for your [lazy evaluation] example here, a complete explanation can be found at the very top ... The "very top" of the django lazy evaluation documentation you pointed to hardly sheds much light on the issue. The documentation just says that certain operations cause database queries, and that some are cached. It's not clear whether doing two similar operations consecutively will result in two database queries (e.g., checking len(dbquery) twice, or checking for truthiness then pulling the first object from a database query). The django documentation does differentiate between evaluated and non-evaluated database queries, but to the developer, it's the same object. Would be much better if an "unevaluated query" and an "evaluated query" were two different types with different semantics. Worse, these lazy evaluation semantics are not terribly pythonic. Checking the length or truthiness of a string, list, set, dict, or tuple is an O(1) operation. Checking the length of a database query may (or may not) make network calls, and may have O(N) performance or worse. Databases queries can give rise to performance bottlenecks and race conditions, and hiding what's actually happening from the developer is a recipe for all sorts of problems.