mongoengine icon indicating copy to clipboard operation
mongoengine copied to clipboard

fix: exception on null embedded scalar values

Open efrederickson opened this issue 3 months ago • 0 comments

Overview

When running a queryset like this:

values = set()
for results in MyModel.objects.filter(Q(a__subfield=1) | Q(b__subfield=1)).values_list("a__subfield", "b__subfield"):
    values.update(results)

Over documents like this:

{"a": {"subfield": 1}, "b": {"subfield":1}},
{"a": {"subfield": 1}, "b": null},
{"a": {"subfield": 1}, "b": {"subfield":1}}

The method _get_scalar will raise an AttributeError on getting the attribute subfield of the second document where b is null.

The workaround currently is to instead do a values_list on (a, b) and then perform null checks on the client side, like this, which is much more verbose (assume get_value is a helper function roughly equivalent to getattr):

values = set()
for (a_par, b_par) in MyModel.objects.filter(Q(a__subfield=1) | Q(b__subfield=1)).values_list("a", "b"):
    if a_par:
       values.add(get_value(a_par, "subfield"))
    if b_par:
       values.add(get_value(b_par, "subfield"))
    ...

This is also less efficient as the whole embedded document must be fetched from the database instead of just the two desired fields. A similar solution using only could be utilized but it is also less elegant.

Fix

Add a simple null check into the _get_scalar method on BaseQuerySet, so that it returns None instead of raising an exception.

efrederickson avatar Aug 20 '25 12:08 efrederickson