Conversation
The JSON/CSV branch used 'fn(doc) or doc', so any falsy result was
discarded and the unconverted row inserted. Exit code 0, no warning:
$ echo '[{"id": 1, "name": "Cleo"}]' | sqlite-utils insert d.db t - --convert '{}'
$ sqlite-utils 'select * from d.db' # -> the original row, not {}
The realistic shape of this is a filter:
--convert 'row if row["ok"] else {}' # meant to drop the bad rows
# every row inserted, including the ones meant to be dropped
'--lines' runs a different expression twelve lines up and has no such
fallback, so the same --convert code is rejected there and silently
accepted here:
--convert 0 JSON input -> exit 0, rows inserted
--convert 0 --lines -> exit 1, Rows must all be dictionaries, got: 0
test_insert_convert_error_messages already asserts that a non-dict
return is rejected (--convert 1); 0, False, [] and "" were the outliers,
purely because they are falsy.
None is the one falsy result that has to keep meaning 'modify doc in
place' - a --convert that is a bare statement returns it, which
test_insert_convert_row_modifying_in_place covers - so the fallback is
now keyed on 'is None' rather than truthiness.
Tests: 7 new cases in tests/test_cli_insert.py, all failing on 6bc1d33.
Suite 1505 passed, 16 skipped. black, flake8, mypy clean. pyright
reports one error and ty two diagnostics, both identical on unmodified
main (tests/test_constructor.py:74 and two unused-type-ignore comments
in db.py/utils.py) and none in the files this touches.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The JSON/CSV branch of
--convertusedfn(doc) or doc, so any falsy result was thrown away and the unconverted row inserted instead — exit code 0, no warning.The realistic shape of this is a filter:
Every row is inserted, including the ones the filter was written to drop, and nothing says so.
--linesalready rejects the same inputTwelve lines earlier the
--linesbranch has no such fallback, so the identical--convertbehaves differently depending only on the input format:Only
Noneshould fall backtest_insert_convert_error_messagesalready asserts that a non-dict return is rejected —--convert 1errors.0,False,[]and""were the outliers, and only because they are falsy.Noneis the one falsy result that has to keep meaning "modifydocin place": a--convertthat is a bare statement returns it, which is whattest_insert_convert_row_modifying_in_placecovers with--convert 'row["is_chicken"] = True'. So the fallback is keyed onis Nonerather than truthiness:What changes for existing users
A
--convertthat returned a truthy dict, or that mutated in place, is unaffected. A--convertthat returned{},0,"",[]orFalsepreviously inserted the input row unchanged and will now either insert what you returned or fail with the same error--convert 1already produced. That is a behaviour change for anyone who relied on the silent fallback — I cannot think of a case where relying on it was intended, but it is a change and worth stating.One thing this does not solve: there is no way to drop a row.
--convert 'row if row["ok"] else {}'inserts a row of nulls rather than skipping it, both before and after. I have left that alone as it is a separate design question.Testing
Testing
Seven cases in
tests/test_cli_insert.py, all failing on6bc1d33:test_insert_convert_falsy_result_is_rejected—0,"",[],Falsetest_insert_convert_returning_none_still_inserts_the_row— pins the in-place signaltest_insert_convert_returning_empty_dict_does_not_insert_the_originaltest_lines_and_json_convert_reject_the_same_falsy_result— the two formats agreeSuite: 1505 passed, 16 skipped.
black --check,flake8andmypyclean.pyrightreports one error andtytwo diagnostics, but all three are identical on unmodifiedmain(tests/test_constructor.py:74, and two unused-type: ignorecomments indb.py/utils.py) and none are in the files this touches.📚 Documentation preview 📚: https://sqlite-utils--889.org.readthedocs.build/en/889/