Closed mcarpenter closed 1 year ago
PR below
Meanwhile, a cheap workaround is to invalidate the registered function cache:
table.convert(...)
db._registered_functions = set()
table.convert(...)
I like the lambda-{uuid}
idea.
That original example passes against main
now.
Summary
When using the API, repeated calls to
Table.convert()
do not work correctly since all conversions quietly use the callable (function, lambda) from the first call toconvert()
only. Subsequent invocations with different callables use the callable from the first invocation only.Example
Output:
Expected:
Explanation
This is some relevant documentation.
Table.convert()
takes aCallable
to perform data conversion on a columnCallable
is passed toDatabase.register_function()
Database.register_function()
uses the callable's__name__
attribute for registration__name__
of<lambda>
: I thought this was the problem, and it was close, but not quite)convert()
first wraps the callable by local functionconvert_value()
register_function()
sees nameconvert_value
for all invocations fromconvert()
register_function()
silently ignores registrations using the same name, retaining only the first such registrationThere's a mismatch between the comments and the code: https://github.com/simonw/sqlite-utils/blob/fc221f9b62ed8624b1d2098e564f525c84497969/sqlite_utils/db.py#L404
but actually the existing function is returned/used instead (as the "registering custom sql functions" doc I linked above says too). Seems like this can be rectified to match the comment?
Suggested fix
I think there are four things:
register_function()
fromconvert()
should have an explicitname=
parameter (to continue usingconvert_value()
and the progress bar).'lambda-{uuid}'
or similar be acceptable?register_function()
really should throw an error on repeated attempts to register a duplicate (function, arity)-pair.See also
458