If I save a plain False to a simple object column in a table using Faster Storage, it gets stored as NULL and I get None back the next time I fetch the row.
Here’s an MWE:
The server code boils down to this, with a settings table that has a name (text) and a value (simple object) column:
from anvil.tables import app_tables
row = app_tables.settings.add_row(name="flag", value=True)
row["value"] = False
print(row["value"]) # False
print(app_tables.settings.get(name="flag")["value"]) # None
app_tables.settings.add_row(name="flag2", value=False)
print(app_tables.settings.get(name="flag2")["value"]) # None
I’d expect both of those fresh reads to give False.
The row object I wrote through still shows False. It’s only a fresh get that comes back with None. True, 0 and {"x": False} all round-trip fine, so it seems to be just a bare False.
Here’s the full output from the MWE:
add_row(value=True): expected True, row['value'] -> True (bool), re-read -> True (bool)
row['value'] = False: expected False, row['value'] -> False (bool), re-read -> None (NoneType) <-- MISMATCH
row['value'] = 0: expected 0, row['value'] -> 0 (int), re-read -> 0 (int)
row['value'] = {'x': False}: expected {'x': False}, row['value'] -> {'x': False} (dict), re-read -> {'x': False} (dict)
add_row(value=False): expected False, row['value'] -> False (bool), re-read -> None (NoneType) <-- MISMATCH
I get exactly the same on the open source app server (1.18.0 with an external PostgreSQL database) with enable_v2: true and enable_split: true in the tables service config. Looking in the database there, the column holds SQL NULL rather than JSON false. With enable_split: false, or with neither flag set, everything comes back as written.
I have a fix ready to roll if a PR to GitHub - anvil-works/anvil-runtime: The runtime engine for hosting Anvil web apps · GitHub would be of use.