clear up confusion with empty string vs None

pull/401/head
Mike Lang 1 year ago committed by Mike Lang
parent 3e873ca5f6
commit ee4a68af50

@ -238,15 +238,15 @@ class SheetSync(object):
self.middleware.mark_modified(row) self.middleware.mark_modified(row)
# Update sheet with any changed outputs # Update sheet with any changed outputs
format_output = lambda v: '' if v is None else v # cast nulls to empty string changed = [col for col in self.output_columns if row.get(col) != getattr(event, col)]
changed = [col for col in self.output_columns if row.get(col) != format_output(getattr(event, col))]
if changed: if changed:
logging.info("Updating sheet row {} with new value(s) for {}".format( logging.info("Updating sheet row {} with new value(s) for {}".format(
row['id'], ', '.join(changed) row['id'], ', '.join(changed)
)) ))
for col in changed: for col in changed:
logging.debug("Writing to sheet {} {!r} -> {!r}".format(col, row.get(col), getattr(event, col)))
self.middleware.write_value( self.middleware.write_value(
row, col, format_output(getattr(event, col)), row, col, getattr(event, col),
) )
rows_changed.labels('output', worksheet).inc() rows_changed.labels('output', worksheet).inc()
self.middleware.mark_modified(row) self.middleware.mark_modified(row)

@ -115,6 +115,7 @@ class SheetsMiddleware():
# Functions take a single arg (the value to parse) and ValueError is # Functions take a single arg (the value to parse) and ValueError is
# interpreted as None. # interpreted as None.
# Columns missing from this map default to simply using the string value. # Columns missing from this map default to simply using the string value.
empty_is_none = lambda v: None if v == "" else v
self.column_parsers = { self.column_parsers = {
'event_start': lambda v: self.parse_bustime(v), 'event_start': lambda v: self.parse_bustime(v),
'event_end': lambda v: self.parse_bustime(v, preserve_dash=True), 'event_end': lambda v: self.parse_bustime(v, preserve_dash=True),
@ -122,6 +123,8 @@ class SheetsMiddleware():
'image_links': lambda v: [link.strip() for link in v.split()] if v.strip() else [], 'image_links': lambda v: [link.strip() for link in v.split()] if v.strip() else [],
'tags': lambda v: [tag.strip() for tag in v.split(',') if tag.strip()], 'tags': lambda v: [tag.strip() for tag in v.split(',') if tag.strip()],
'id': lambda v: v if v.strip() else None, 'id': lambda v: v if v.strip() else None,
'error': empty_is_none,
'video_link': empty_is_none,
} }
# tracks when to do inactive checks # tracks when to do inactive checks
self.sync_count = 0 self.sync_count = 0
@ -241,6 +244,10 @@ class SheetsMiddleware():
def write_value(self, row, key, value): def write_value(self, row, key, value):
"""Write key=value to the given row, as identified by worksheet + row dict.""" """Write key=value to the given row, as identified by worksheet + row dict."""
# You can't write null to a spreadsheet, so cast to empty string instead.
# For values where this is needed, they should be parsed so that '' -> None.
if value is None:
value = ''
return self.client.write_value( return self.client.write_value(
self.sheet_id, self.sheet_id,
row["sheet_name"], row["sheet_name"],

@ -69,7 +69,6 @@ class StreamLogMiddleware:
'event_end': lambda v: None if v is None else parse_utc_only(v), 'event_end': lambda v: None if v is None else parse_utc_only(v),
'category': lambda v: v["name"], 'category': lambda v: v["name"],
'state': lambda v: None if v is None else v.upper(), 'state': lambda v: None if v is None else v.upper(),
'video_link': lambda v: '' if v is None else v,
} }
# Maps DB column names to an encode function to convert from internal format to streamlog. # Maps DB column names to an encode function to convert from internal format to streamlog.
# Omitted columns act as the identity function. # Omitted columns act as the identity function.

Loading…
Cancel
Save