Skip to content

Commit a3e864a

Browse files
authored
Merge branch 'master' into comment
2 parents 3cd6447 + 934d7ce commit a3e864a

9 files changed

+2311
-597
lines changed

flattentool/input.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,19 @@ def convert_type(type_string, value, timezone = pytz.timezone('UTC')):
9898
raise ValueError('Unrecognised type: "{}"'.format(type_string))
9999

100100

101+
def warnings_for_ignored_columns(v, extra_message):
102+
if isinstance(v, Cell):
103+
warn('Column {} has been ignored, {}'.format(v.cell_location[3], extra_message))
104+
elif isinstance(v, dict):
105+
for x in v.values():
106+
warnings_for_ignored_columns(x, extra_message)
107+
elif isinstance(v, TemporaryDict):
108+
for x in v.to_list():
109+
warnings_for_ignored_columns(x, extra_message)
110+
else:
111+
raise ValueError()
112+
113+
101114
def merge(base, mergee, debug_info=None):
102115
if not debug_info:
103116
debug_info = {}
@@ -108,6 +121,9 @@ def merge(base, mergee, debug_info=None):
108121
value = v
109122
if key in base:
110123
if isinstance(value, TemporaryDict):
124+
if not isinstance(base[key], TemporaryDict):
125+
warnings_for_ignored_columns(v, 'because it treats {} as an array, but another column does not'.format(key))
126+
continue
111127
for temporarydict_key, temporarydict_value in value.items():
112128
if temporarydict_key in base[key]:
113129
merge(base[key][temporarydict_key], temporarydict_value, debug_info)
@@ -116,9 +132,18 @@ def merge(base, mergee, debug_info=None):
116132
base[key][temporarydict_key] = temporarydict_value
117133
for temporarydict_value in value.items_no_keyfield:
118134
base[key].items_no_keyfield.append(temporarydict_value)
119-
elif isinstance(value, dict) and isinstance(base[key], dict):
120-
merge(base[key], value, debug_info)
135+
elif isinstance(value, dict):
136+
if isinstance(base[key], dict):
137+
merge(base[key], value, debug_info)
138+
else:
139+
warnings_for_ignored_columns(v, 'because it treats {} as an object, but another column does not'.format(key))
121140
else:
141+
if not isinstance(base[key], Cell):
142+
id_info = '{} "{}"'.format(debug_info.get('id_name'), debug_info.get(debug_info.get('id_name')))
143+
if debug_info.get('root_id'):
144+
id_info = '{} "{}", '.format(debug_info.get('root_id'), debug_info.get('root_id_or_none'))+id_info
145+
warnings_for_ignored_columns(v, 'because another column treats it as an array or object'.format(key))
146+
continue
122147
base_value = base[key].cell_value
123148
if base_value != value:
124149
id_info = '{} "{}"'.format(debug_info.get('id_name'), debug_info.get(debug_info.get('id_name')))
@@ -149,7 +174,7 @@ def convert_dict_titles(self, dicts, title_lookup=None):
149174
150175
"""
151176
if self.parser:
152-
title_lookup = title_lookup or self.parser.title_lookup
177+
title_lookup = self.parser.title_lookup
153178
for d in dicts:
154179
if title_lookup:
155180
yield OrderedDict([(title_lookup.lookup_header(k), v) for k,v in d.items()])

flattentool/json_input.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,21 @@ class BadlyFormedJSONError(ValueError):
2323
pass
2424

2525

26-
def sheet_key_field(sheet, key, id_key=None):
26+
def sheet_key_field(sheet, key):
2727
if key not in sheet:
2828
sheet.append(key)
2929
return key
3030

31-
def sheet_key_title(sheet, key, id_key=None):
31+
def sheet_key_title(sheet, key):
3232
"""
3333
If the key has a corresponding title, return that. If doesn't, create it in the sheet and return it.
3434
3535
"""
36-
if id_key: # call sheet_key_field instead
37-
return sheet_key_field(sheet, key, id_key)
38-
title_lookup = {v: k for k, v in sheet.titles.items()}
39-
if key in title_lookup:
40-
return title_lookup[key]
36+
if key in sheet.titles:
37+
return sheet.titles[key]
4138
else:
42-
sheet.append(key)
39+
if key not in sheet:
40+
sheet.append(key)
4341
return key
4442

4543

@@ -111,13 +109,13 @@ def parse_json_dict(self, json_dict, sheet, json_key=None, parent_name='', flatt
111109
if top_level_of_sub_sheet:
112110
# Only add the IDs for the top level of object in an array
113111
for k, v in parent_id_fields.items():
114-
flattened_dict[sheet_key(sheet, k, id_key=json_key)] = v
112+
flattened_dict[sheet_key(sheet, k)] = v
115113

116114
if self.root_id and self.root_id in json_dict:
117-
parent_id_fields[self.root_id] = json_dict[self.root_id]
115+
parent_id_fields[sheet_key(sheet, self.root_id)] = json_dict[self.root_id]
118116

119117
if 'id' in json_dict:
120-
parent_id_fields[parent_name+'id'] = json_dict['id']
118+
parent_id_fields[sheet_key(sheet, parent_name+'id')] = json_dict['id']
121119

122120

123121
for key, value in json_dict.items():
@@ -142,7 +140,12 @@ def parse_json_dict(self, json_dict, sheet, json_key=None, parent_name='', flatt
142140
if self.rollup and parent_name == '': # Rollup only currently possible to main sheet
143141
if len(value) == 1:
144142
for k, v in value[0].items():
145-
if parent_name+key+'/0/'+k in self.schema_parser.main_sheet:
143+
if self.use_titles and parent_name+key+'/0/'+k in self.schema_parser.main_sheet.titles:
144+
if type(v) in BASIC_TYPES:
145+
flattened_dict[sheet_key_title(sheet, parent_name+key+'/0/'+k)] = v
146+
else:
147+
raise ValueError('Rolled up values must be basic types')
148+
elif not self.use_titles and parent_name+key+'/0/'+k in self.schema_parser.main_sheet:
146149
if type(v) in BASIC_TYPES:
147150
flattened_dict[sheet_key(sheet, parent_name+key+'/0/'+k)] = v
148151
else:

flattentool/schema.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ def parse(self):
104104
warn('Field {} does not have a title, skipping.'.format(field))
105105
else:
106106
self.main_sheet.append(title)
107+
self.main_sheet.titles[field] = title
107108
else:
108109
self.main_sheet.append(field)
109110

@@ -174,26 +175,29 @@ def parse_schema_dict(self, parent_path, schema_dict, parent_id_fields=None, tit
174175

175176
for field in id_fields:
176177
sub_sheet.add_field(field, id_field=True)
178+
sub_sheet.titles[title_lookup.lookup_header(field)] = field
177179
fields = self.parse_schema_dict(
178180
parent_path+property_name+'/0',
179181
property_schema_dict['items'],
180182
parent_id_fields=id_fields,
181183
title_lookup=title_lookup.get(title),
182184
parent_title=parent_title+title+':' if parent_title is not None and title else None)
183-
184185
rolledUp = set()
185186

186187
for field, child_title in fields:
188+
full_path = parent_path+property_name+'/0/'+field
187189
if self.use_titles:
188190
if not child_title or parent_title is None:
189191
warn('Field {}{}/0/{} is missing a title, skipping.'.format(parent_path, property_name, field))
190192
elif not title:
191193
warn('Field {}{} does not have a title, skipping it and all its children.'.format(parent_path, property_name))
192194
else:
193195
# This code only works for arrays that are at 0 or 1 layer of nesting
194-
sub_sheet.add_field(parent_title+title+':'+child_title)
196+
full_title = parent_title+title+':'+child_title
197+
sub_sheet.add_field(full_title)
198+
sub_sheet.titles[full_path] = full_title
195199
else:
196-
sub_sheet.add_field(parent_path+property_name+'/0/'+field)
200+
sub_sheet.add_field(full_path)
197201
if self.rollup and 'rollUp' in property_schema_dict and field in property_schema_dict['rollUp']:
198202
rolledUp.add(field)
199203
yield property_name+'/0/'+field, (title+':'+child_title if title and child_title else None)
@@ -204,7 +208,7 @@ def parse_schema_dict(self, parent_path, schema_dict, parent_id_fields=None, tit
204208
if missedRollUp:
205209
warn('{} in rollUp but not in schema'.format(', '.join(missedRollUp)))
206210
else:
207-
raise ValueError
211+
raise ValueError('Unknown type_set: {}, did you forget to explicity set the "type" key on "items"?'.format(type_set))
208212
elif 'string' in property_type_set or not property_type_set:
209213
self.flattened[parent_path.replace('/0/', '/')+property_name] = "string"
210214
yield property_name, title

0 commit comments

Comments
 (0)