Bail on incorrect headers

This commit is contained in:
Scot Hacker 2019-03-10 15:03:18 -07:00
parent 37a698c77b
commit aa9bdacb18
3 changed files with 67 additions and 55 deletions

View file

@ -37,17 +37,20 @@ class Command(BaseCommand):
# Report successes, failures and summaries # Report successes, failures and summaries
print() print()
for upsert_msg in results.get("upserts"): if results.get("upserts"):
print(upsert_msg) for upsert_msg in results.get("upserts"):
print(upsert_msg)
# Stored errors has the form: # Stored errors has the form:
# self.errors = [{3: ["Incorrect foo", "Non-existent bar"]}, {7: [...]}] # self.errors = [{3: ["Incorrect foo", "Non-existent bar"]}, {7: [...]}]
for error_dict in results.get("errors"): if results.get("errors"):
for k, error_list in error_dict.items(): for error_dict in results.get("errors"):
print(f"\nSkipped CSV row {k}:") for k, error_list in error_dict.items():
for msg in error_list: print(f"\nSkipped CSV row {k}:")
print(f"- {msg}") for msg in error_list:
print(f"- {msg}")
print() print()
for summary_msg in results.get("summaries"): if results.get("summaries"):
print(summary_msg) for summary_msg in results.get("summaries"):
print(summary_msg)

View file

@ -17,9 +17,11 @@ class CSVImporter:
""" """
def __init__(self): def __init__(self):
self.error_msgs = [] self.results = {
self.upsert_msgs = [] "errors": [],
self.summary_msgs = [] "upserts": [],
"summaries": [],
}
self.line_count = 0 self.line_count = 0
self.upsert_count = 0 self.upsert_count = 0
@ -39,6 +41,13 @@ class CSVImporter:
# fileobj comes from browser upload (in-memory) # fileobj comes from browser upload (in-memory)
csv_reader = csv.DictReader(codecs.iterdecode(fileobj, "utf-8")) csv_reader = csv.DictReader(codecs.iterdecode(fileobj, "utf-8"))
# DI check: Do we have expected header row?
header = csv_reader.fieldnames
expected = ['Title', 'Group', 'Task List', 'Created Date', 'Due Date', 'Completed', 'Created By', 'Assigned To', 'Note', 'Priority']
if not header == expected:
self.results.get('summaries').append(f"Inbound data does not have expected columns.\nShould be: {expected}")
return self.results
for row in csv_reader: for row in csv_reader:
self.line_count += 1 self.line_count += 1
@ -64,18 +73,13 @@ class CSVImporter:
f'Upserted task {obj.id}: "{obj.title}"' f'Upserted task {obj.id}: "{obj.title}"'
f' in list "{obj.task_list}" (group "{obj.task_list.group}")' f' in list "{obj.task_list}" (group "{obj.task_list.group}")'
) )
self.upsert_msgs.append(msg) self.results.get("upserts").append(msg)
self.summary_msgs.append(f"\nProcessed {self.line_count} CSV rows") self.results.get('summaries').append(f"\nProcessed {self.line_count} CSV rows")
self.summary_msgs.append(f"Upserted {self.upsert_count} rows") self.results.get('summaries').append(f"Upserted {self.upsert_count} rows")
self.summary_msgs.append(f"Skipped {self.line_count - self.upsert_count} rows") self.results.get('summaries').append(f"Skipped {self.line_count - self.upsert_count} rows")
_res = { return self.results
"errors": self.error_msgs,
"upserts": self.upsert_msgs,
"summaries": self.summary_msgs,
}
return _res
def validate_row(self, row): def validate_row(self, row):
"""Perform data integrity checks and set default values. Returns a valid object for insertion, or False. """Perform data integrity checks and set default values. Returns a valid object for insertion, or False.
@ -174,7 +178,7 @@ class CSVImporter:
# ####################### # #######################
if row_errors: if row_errors:
self.error_msgs.append({self.line_count: row_errors}) self.results.get("errors").append({self.line_count: row_errors})
return False return False
# No errors: # No errors:

View file

@ -21,40 +21,45 @@
</div> </div>
<div class="card-body"> <div class="card-body">
<p> {% if results.summaries %}
<b>Summary:</b> <p>
</p> <b>Summary:</b>
<ul> </p>
{% for line in results.summaries %} <ul>
<li>{{ line }}</li> {% for line in results.summaries %}
{% endfor %} <li>{{ line }}</li>
</ul>
<p>
<b>Upserts (tasks created or updated):</b>
</p>
<ul>
{% for line in results.upserts %}
<li>{{ line }}</li>
{% endfor %}
</ul>
<p>
<b>Errors (tasks NOT created or updated):</b>
</p>
<ul>
{% for error_row in results.errors %}
{% for k, error_list in error_row.items %}
<li>CSV row {{ k }}</li>
<ul>
{% for err in error_list %}
<li>{{ err }}</li>
{% endfor %}
</ul>
{% endfor %} {% endfor %}
</ul>
{% endif %}
{% endfor %} {% if results.upserts %}
</ul> <p>
<b>Upserts (tasks created or updated):</b>
</p>
<ul>
{% for line in results.upserts %}
<li>{{ line }}</li>
{% endfor %}
</ul>
{% endif %}
{% if results.errors %}
<p>
<b>Errors (tasks NOT created or updated):</b>
</p>
<ul>
{% for error_row in results.errors %}
{% for k, error_list in error_row.items %}
<li>CSV row {{ k }}</li>
<ul>
{% for err in error_list %}
<li>{{ err }}</li>
{% endfor %}
</ul>
{% endfor %}
{% endfor %}
</ul>
{% endif %}
</div> </div>