From ee4a68af504d1215ce2992816225bfbe16456912 Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Fri, 13 Oct 2023 00:43:22 +1100 Subject: [PATCH] clear up confusion with empty string vs None --- sheetsync/sheetsync/main.py | 6 +++--- sheetsync/sheetsync/sheets.py | 7 +++++++ sheetsync/sheetsync/streamlog.py | 1 - 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/sheetsync/sheetsync/main.py b/sheetsync/sheetsync/main.py index e018f67..fb376aa 100644 --- a/sheetsync/sheetsync/main.py +++ b/sheetsync/sheetsync/main.py @@ -238,15 +238,15 @@ class SheetSync(object): self.middleware.mark_modified(row) # 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) != format_output(getattr(event, col))] + changed = [col for col in self.output_columns if row.get(col) != getattr(event, col)] if changed: logging.info("Updating sheet row {} with new value(s) for {}".format( row['id'], ', '.join(changed) )) for col in changed: + logging.debug("Writing to sheet {} {!r} -> {!r}".format(col, row.get(col), getattr(event, col))) self.middleware.write_value( - row, col, format_output(getattr(event, col)), + row, col, getattr(event, col), ) rows_changed.labels('output', worksheet).inc() self.middleware.mark_modified(row) diff --git a/sheetsync/sheetsync/sheets.py b/sheetsync/sheetsync/sheets.py index 3cd5889..a9298f5 100644 --- a/sheetsync/sheetsync/sheets.py +++ b/sheetsync/sheetsync/sheets.py @@ -115,6 +115,7 @@ class SheetsMiddleware(): # Functions take a single arg (the value to parse) and ValueError is # interpreted as None. # 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 = { 'event_start': lambda v: self.parse_bustime(v), '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 [], 'tags': lambda v: [tag.strip() for tag in v.split(',') if tag.strip()], 'id': lambda v: v if v.strip() else None, + 'error': empty_is_none, + 'video_link': empty_is_none, } # tracks when to do inactive checks self.sync_count = 0 @@ -241,6 +244,10 @@ class SheetsMiddleware(): def write_value(self, row, key, value): """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( self.sheet_id, row["sheet_name"], diff --git a/sheetsync/sheetsync/streamlog.py b/sheetsync/sheetsync/streamlog.py index b655401..bbfc258 100644 --- a/sheetsync/sheetsync/streamlog.py +++ b/sheetsync/sheetsync/streamlog.py @@ -69,7 +69,6 @@ class StreamLogMiddleware: 'event_end': lambda v: None if v is None else parse_utc_only(v), 'category': lambda v: v["name"], '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. # Omitted columns act as the identity function.