'Load the synthetic fields that are stored in a different table from the
main object.
This method doesn\'t take care of loading synthetic fields that aren\'t
stored in the DB, e.g. \'shared\' in RBAC policy.'

def load_synthetic_db_fields(self, db_obj=None):

    clsname = self.__class__.__name__
    for field in self.synthetic_fields:
        try:
            objclasses = obj_base.VersionedObjectRegistry.obj_classes().get(self.fields[field].objname)
        except AttributeError:
            continue
        if (not objclasses):
            continue
        objclass = objclasses[0]
        foreign_keys = objclass.foreign_keys.get(clsname)
        if (not foreign_keys):
            raise o_exc.NeutronSyntheticFieldsForeignKeysNotFound(parent=clsname, child=objclass.__name__)
        if (len(foreign_keys.keys()) > 1):
            raise o_exc.NeutronSyntheticFieldMultipleForeignKeys(field=field)
        synthetic_field_db_name = self.fields_need_translation.get(field, field)
        synth_db_objs = (db_obj.get(synthetic_field_db_name, None) if db_obj else None)
        if (synth_db_objs is not None):
            if (not isinstance(synth_db_objs, list)):
                synth_db_objs = [synth_db_objs]
            synth_objs = [objclass._load_object(self.obj_context, obj) for obj in synth_db_objs]
        else:
            synth_objs = objclass.get_objects(self.obj_context, **{k: (getattr(self, v) if (v in self) else db_obj.get(v)) for (k, v) in foreign_keys.items()})
        if isinstance(self.fields[field], obj_fields.ObjectField):
            setattr(self, field, (synth_objs[0] if synth_objs else None))
        else:
            setattr(self, field, synth_objs)
        self.obj_reset_changes([field])
