remove dotted keys, a terrible idea
This commit is contained in:
parent
2cde3badad
commit
293c7a0a78
@ -236,8 +236,7 @@ class FieldCopier(Filter):
|
|||||||
def process_record(self, record):
|
def process_record(self, record):
|
||||||
# mapping is dest:source
|
# mapping is dest:source
|
||||||
for dest, source in self._copy_mapping.iteritems():
|
for dest, source in self._copy_mapping.iteritems():
|
||||||
srcval = utils.dotted_key_lookup(record, source)
|
record[dest] = record[source]
|
||||||
utils.dotted_key_set(record, dest, srcval)
|
|
||||||
return record
|
return record
|
||||||
|
|
||||||
class FieldRenamer(Filter):
|
class FieldRenamer(Filter):
|
||||||
@ -254,12 +253,11 @@ class FieldRenamer(Filter):
|
|||||||
# mapping is dest:source
|
# mapping is dest:source
|
||||||
for dest, source in self._rename_mapping.iteritems():
|
for dest, source in self._rename_mapping.iteritems():
|
||||||
try:
|
try:
|
||||||
srcval = utils.dotted_key_pop(record, source)
|
record[dest] = record.pop(source)
|
||||||
utils.dotted_key_set(record, dest, srcval)
|
|
||||||
except KeyError:
|
except KeyError:
|
||||||
# silently pass if source key didn't exist
|
# silently pass if source key didn't exist
|
||||||
pass
|
pass
|
||||||
return record
|
return record
|
||||||
|
|
||||||
class Splitter(Filter):
|
class Splitter(Filter):
|
||||||
""" Filter that splits nested data into different paths.
|
""" Filter that splits nested data into different paths.
|
||||||
|
@ -67,100 +67,6 @@ def str_or_list(obj):
|
|||||||
else:
|
else:
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def dotted_key_lookup(dict_, dotted_key, default=KeyError, separator='.'):
|
|
||||||
"""
|
|
||||||
Do a lookup within dict_ by the various elements of dotted_key.
|
|
||||||
|
|
||||||
Optionally specify a default to return if key does not exist (similar
|
|
||||||
to default)
|
|
||||||
|
|
||||||
>>> d = {'a': {'b': {'c': 3} } }
|
|
||||||
>>> dotted_key_lookup(d, 'a.b.c')
|
|
||||||
3
|
|
||||||
>>> dotted_key_lookup(d, 'a.z', -1)
|
|
||||||
-1
|
|
||||||
>>> dotted_key_lookup(d, 'a|b|c', separator='|')
|
|
||||||
3
|
|
||||||
"""
|
|
||||||
val = dict_
|
|
||||||
try:
|
|
||||||
for key in dotted_key.split(separator):
|
|
||||||
if isinstance(val, dict):
|
|
||||||
val = val[key]
|
|
||||||
elif isinstance(val, (list,tuple)):
|
|
||||||
val = val[int(key)]
|
|
||||||
else:
|
|
||||||
val = getattr(val, key)
|
|
||||||
except (KeyError, IndexError, AttributeError):
|
|
||||||
if default is KeyError:
|
|
||||||
raise
|
|
||||||
val = default
|
|
||||||
return val
|
|
||||||
|
|
||||||
def dotted_key_pop(dict_, dotted_key, default=KeyError, separator='.'):
|
|
||||||
"""
|
|
||||||
Delete a value within dict_ by the various elements of dotted_key.
|
|
||||||
"""
|
|
||||||
val = dict_
|
|
||||||
try:
|
|
||||||
key_parts = dotted_key.split(separator)
|
|
||||||
for key in key_parts[:-1]:
|
|
||||||
if isinstance(val, dict):
|
|
||||||
val = val[key]
|
|
||||||
elif isinstance(val, (list,tuple)):
|
|
||||||
val = val[int(key)]
|
|
||||||
else:
|
|
||||||
val = getattr(val, key)
|
|
||||||
|
|
||||||
# now with just the final part of the key
|
|
||||||
key = key_parts[-1]
|
|
||||||
if isinstance(val, dict):
|
|
||||||
retval = val[key]
|
|
||||||
del val[key]
|
|
||||||
elif isinstance(val, (list,tuple)):
|
|
||||||
retval = val[int(key)]
|
|
||||||
del val[int(key)]
|
|
||||||
else:
|
|
||||||
retval = getattr(val, key)
|
|
||||||
delattr(val, key)
|
|
||||||
except (KeyError, IndexError, AttributeError):
|
|
||||||
if default is KeyError:
|
|
||||||
raise
|
|
||||||
retval = default
|
|
||||||
return retval
|
|
||||||
|
|
||||||
def dotted_key_set(dict_or_list, dotted_key, value, separator='.'):
|
|
||||||
"""
|
|
||||||
Set a value within dict_ using a dotted_key.
|
|
||||||
|
|
||||||
>>> d = {}
|
|
||||||
>>> dotted_key_set(d, 'a.b.c', 123}
|
|
||||||
>>> d
|
|
||||||
{'a': {'b': {'c': 123}}}
|
|
||||||
"""
|
|
||||||
|
|
||||||
# split key into composite parts
|
|
||||||
keys = dotted_key.split(separator)
|
|
||||||
|
|
||||||
for i,key in enumerate(keys):
|
|
||||||
|
|
||||||
# if current location is a dictionary: traverse inward until @ last key
|
|
||||||
# set value when last key is reached
|
|
||||||
if isinstance(dict_or_list, dict):
|
|
||||||
if i == len(keys)-1:
|
|
||||||
dict_or_list[key] = value
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
dict_or_list = dict_or_list[key]
|
|
||||||
except KeyError:
|
|
||||||
break
|
|
||||||
|
|
||||||
# if current location is a list: call dotted_key_set on each element
|
|
||||||
elif isinstance(dict_or_list, (tuple, list)):
|
|
||||||
newkey = separator.join(keys[i:])
|
|
||||||
for item in dict_or_list:
|
|
||||||
dotted_key_set(item, newkey, value, separator)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# utility classes
|
# utility classes
|
||||||
#
|
#
|
||||||
@ -188,4 +94,4 @@ class Files(object):
|
|||||||
f = open(path)
|
f = open(path)
|
||||||
for line in f:
|
for line in f:
|
||||||
yield line
|
yield line
|
||||||
f.close()
|
f.close()
|
||||||
|
Loading…
Reference in New Issue
Block a user