-
-
Notifications
You must be signed in to change notification settings - Fork 121
Description
Summary
By design, Table.convert()
does not attempt conversion of falsey values (None
, ""
, 0
, ...). This is surprising (directly contradicts the docstring) and convert()
may quietly skip cells where the user assumed a conversion would take place.
Example
Increment a column of integers by one
from sqlite_utils import Database
db = Database(memory=True)
table = db['table']
col = 'x'
table.insert_all([{col: 0}, {col:1}])
print(table.get(1)) # 0
print(table.get(2)) # 1
print()
table.convert(col, lambda x: x+1)
print(table.get(1)) # got 0, expected 1 ⚠⚠⚠
print(table.get(2)) # got 2, expected 2
Another example might be, say, transforming cells containing empty string to NULL
.
Discussion
This was, I think, a pragmatic choice so that consumers can skip writing guard clauses for these falsey values (particularly from the CLI). But this surprising undocumented behavior can lead to incorrect data. I don't think this is a good trade-off between convenience and correctness.
In the absence of this convenience users will either have to write guard clauses into their conversion expressions (or adapt the called function to do the same), so:
fn(value) if value else value
instead of:
fn(value)
This is more typing and sometimes I will forget, and there will be errors. (But they will be noisy errors, which is a good thing).
Such a change will certainly inconvenience some existing consumers; there will be some breakage. But I think this is worth it to avoid quietly not converting some values by default, which can lead to quietly bad data.
I have a PR that I will attach, please take a look and see what you think.