@@ -123,6 +123,7 @@ def __getattr__(self, item):
123123
124124
125125_none = object ()
126+ _none_as_none = object ()
126127
127128
128129def _get_column (model , column_or_name ) -> Column :
@@ -212,9 +213,11 @@ def __init__(self, model, *columns, **extras):
212213 self .extras = dict ((key , self .get (value )) for key , value in extras .items ())
213214 self .on_clause = None
214215
215- def _do_load (self , row ):
216+ def _do_load (self , row , none_as_none ):
217+ # none_as_none indicates that in the case of every column of the object is
218+ # None, whether a None or empty instance of the model should be returned.
216219 values = dict ((c .name , row [c ]) for c in self .columns if c in row )
217- if all ((v is None ) for v in values .values ()):
220+ if none_as_none and all ((v is None ) for v in values .values ()):
218221 return None
219222 rv = self .model ()
220223 for c in self .columns :
@@ -233,26 +236,29 @@ def do_load(self, row, context):
233236 result is distinct.
234237 """
235238
239+ if context is None :
240+ context = {}
236241 distinct = True
237242 if self ._distinct :
238- if context is None :
239- context = {}
240243 ctx = context .setdefault (self ._distinct , {})
241244 key = tuple (row [col ] for col in self ._distinct )
242245 rv = ctx .get (key , _none )
243246 if rv is _none :
244- rv = self ._do_load (row )
247+ rv = self ._do_load (row , context . get ( _none_as_none , False ) )
245248 ctx [key ] = rv
246249 else :
247250 distinct = False
248251 else :
249- rv = self ._do_load (row )
252+ rv = self ._do_load (row , context . get ( _none_as_none , False ) )
250253
251254 if rv is None :
252255 return None , None
253256 else :
254257 for key , value in self .extras .items ():
258+ context .setdefault (_none_as_none , True )
255259 value , distinct_ = value .do_load (row , context )
260+ # _none_as_none should not be propagated to parents
261+ context .pop (_none_as_none , 0 )
256262 if distinct_ is None :
257263 continue
258264
0 commit comments