From: Thierry Parmentelat Date: Fri, 5 Jun 2015 11:57:41 +0000 (+0200) Subject: workaround the mysterious issue with sqlalchemy that returns instances of RegAuthorit... X-Git-Tag: sfa-3.1-17~1 X-Git-Url: http://git.onelab.eu/?p=sfa.git;a=commitdiff_plain;h=5ce17831ca493a16e2a9c82c219ca5be14af7709 workaround the mysterious issue with sqlalchemy that returns instances of RegAuthority that do not have their __dict__ in line with the object's contents (specifically missing 'name') a possibly other instance of that same issue was worked around in Update() using an extra print statement, which I prefer to leave as is for now as I cannot test that thoroughly, but a similar approach would probably be a solution in this case as well --- diff --git a/sfa/managers/registry_manager.py b/sfa/managers/registry_manager.py index 8f65e068..1eafc10f 100644 --- a/sfa/managers/registry_manager.py +++ b/sfa/managers/registry_manager.py @@ -295,12 +295,11 @@ class RegistryManager: # logger.debug("non recursive mode, found {} local records".format(len(records))) # so that sfi list can show more than plain names... for record in records: - # xxx mystery - again this useless statement is key here so that - # resulting records have their __dict__ field actually in line with the - # object's contents; was first observed with authorities' 'name' column + # xxx mystery - see also the bottom of model.py + # resulting records have been observed to not always have + # their __dict__ actually in line with the object's contents; + # was first observed with authorities' 'name' column # that would be missing from result as received by client - # record.todict() is the place where __dict__ is used - print "DO NOT REMOVE ME before augment_with_sfa_builtins, record={}".format(record) augment_with_sfa_builtins(record) record_dicts = [ record.record_to_dict(exclude_types=(InstrumentedList,)) for record in records ] @@ -499,11 +498,16 @@ class RegistryManager: record.email = email # update the PLC information that was specified with the record - # xxx mystery: oddly enough, without this useless statement, + # xxx mystery -- see also the bottom of model.py, + # oddly enough, without this useless statement, # record.__dict__ as received by the driver seems to be off - # anyway the driver should receive an object + # anyway the driver should receive an object # (and then extract __dict__ itself if needed) print "DO NOT REMOVE ME before driver.update, record={}".format(record) + # as of June 2015: I suspect we could remove that print line above and replace it with + # augment_with_sfa_builtins(record) + # instead, that checks for these fields, like it is done above in List() + # but that would need to be confirmed by more extensive tests new_key_pointer = -1 try: (pointer, new_key_pointer) = api.driver.update (record.__dict__, new_record.__dict__, hrn, new_key) diff --git a/sfa/storage/model.py b/sfa/storage/model.py index b31517a5..051ba87e 100644 --- a/sfa/storage/model.py +++ b/sfa/storage/model.py @@ -489,15 +489,35 @@ augment_map = {'authority': {'reg-pis' : 'reg_pis',}, } +# xxx mystery +# the way we use sqlalchemy might be a little wrong +# in any case what has been observed is that (Reg)Records as returned by an sqlalchemy +# query not always have their __dict__ properly adjusted +# typically a RegAuthority object would have its object.name set properly, but +# object.__dict__ has no 'name' key +# which is an issue because we rely on __dict__ for many things, in particular this +# is what gets exposed to the drivers (this is historical and dates back before sqlalchemy) +# so it is recommended to always run this function that will make sure +# that such built-in fields are properly set in __dict__ too +# def augment_with_sfa_builtins(local_record): # don't ruin the import of that file in a client world from sfa.util.xrn import Xrn # add a 'urn' field setattr(local_record, 'reg-urn', Xrn(xrn=local_record.hrn, type=local_record.type).urn) # users have keys and this is needed to synthesize 'users' sent over to CreateSliver + fields_to_check = [] if local_record.type == 'user': user_keys = [ key.key for key in local_record.reg_keys ] setattr(local_record, 'reg-keys', user_keys) + fields_to_check = ['email'] + elif local_record.type == 'authority': + fields_to_check = ['name'] + for field in fields_to_check: + if not field in local_record.__dict__: + logger.debug("augment_with_sfa_builtins: hotfixing missing '{}' in {}" + .format(field, local_record.hrn)) + local_record.__dict__[field] = getattr(local_record, field) # search in map according to record type type_map = augment_map.get(local_record.type, {}) # use type-dep. map to do the job