@@ -206,25 +206,52 @@ class ModelLoader(Loader):
206206 def __init__ (self , model , * columns , ** extras ):
207207 self .model = model
208208 self ._distinct = None
209+
210+ self ._columns = None
211+ self ._prop_column_map = None
212+
209213 if columns :
210- self .columns = [ _get_column (model , name ) for name in columns ]
214+ self .columns = tuple ( _get_column (model , name ) for name in columns )
211215 else :
212216 self .columns = model
213217 self .extras = dict ((key , self .get (value )) for key , value in extras .items ())
214218 self .on_clause = None
215219
220+ @property
221+ def columns (self ):
222+ return self ._columns
223+
224+ @columns .setter
225+ def columns (self , value ):
226+ self ._columns = value
227+ self ._prop_column_map = {
228+ self .model ._column_name_map .invert_get (c .name ): c for c in self .columns
229+ }
230+
216231 def _do_load (self , row , none_as_none ):
217232 # none_as_none indicates that in the case of every column of the object is
218233 # None, whether a None or empty instance of the model should be returned.
219- values = dict ((c .name , row [c ]) for c in self .columns if c in row )
220- if none_as_none and all ((v is None ) for v in values .values ()):
234+ all_is_none = none_as_none
235+
236+ values = {}
237+
238+ for prop_name , column in self ._prop_column_map .items ():
239+ try :
240+ row_value = row [column ]
241+ except KeyError :
242+ # model is partially loaded skip
243+ continue
244+
245+ values [prop_name ] = row_value
246+ all_is_none &= row_value is None
247+
248+ if all_is_none :
221249 return None
250+
222251 rv = self .model ()
223- for c in self .columns :
224- if c in row :
225- # noinspection PyProtectedMember
226- instance_key = self .model ._column_name_map .invert_get (c .name )
227- rv .__values__ [instance_key ] = row [c ]
252+ # no need to update, model just created
253+ rv .__values__ = values
254+
228255 return rv
229256
230257 def do_load (self , row , context ):
@@ -300,7 +327,7 @@ def load(self, *columns, **extras):
300327 """
301328
302329 if columns :
303- self .columns = [ _get_column (self .model , name ) for name in columns ]
330+ self .columns = tuple ( _get_column (self .model , name ) for name in columns )
304331
305332 self .extras .update ((key , self .get (value )) for key , value in extras .items ())
306333 return self
0 commit comments