-
Notifications
You must be signed in to change notification settings - Fork 91
Add replace=True parameter to create_function for Python UDFs #459
-
Feature Request: replace parameter for create_function
Motivation
When developing with Python UDFs, updating an existing function requires two separate calls with a try/except pattern:
try: con.remove_function("my_udf") except: pass con.create_function("my_udf", my_udf)
This is error-prone and verbose, especially when managing multiple UDFs in a bootstrap registration function. It also masks real errors since the bare except silently swallows any exception from remove_function.
Current Behavior
Calling create_function with an existing name raises:
NotImplementedException: A function by the name of 'x' is already created,
creating multiple functions with the same name is not supported yet,
please remove it first
Proposed Solution
Add a replace parameter to create_function:
con.create_function("my_udf", my_udf, replace=True)
Or alternatively, a dedicated method (consistent with SQL's CREATE OR REPLACE semantics):
con.create_or_replace_function("my_udf", my_udf)
The replace=True approach is preferred as it avoids adding a new method to the API surface and is consistent with how other parameters in create_function work.
Additional Context
This pattern is especially common during development and in notebook environments where cells are re-run frequently. The SQL CREATE OR REPLACE MACRO already supports this semantic — it would be natural to expose the same capability in the Python API.
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 1 comment
-
fwiw, this matches what I see on duckdb==1.4.4. replace isn’t in the current Python stub/signature, duplicate create_function throws NotImplementedException, and removing a missing one throws InvalidInputException.
Until replace=True exists, I’d probably avoid the bare except and only ignore the "not registered yet" case:
import duckdb def create_or_replace_udf(con, name, fn, parameters=None, return_type=None): try: con.remove_function(name) except duckdb.InvalidInputException as e: if "No function by the name" not in str(e): raise return con.create_function(name, fn, parameters, return_type)
I tested that with an in-memory connection by registering x + 1, rerunning it with x + 2, and the second version was the one DuckDB used. So yeah, replace=True would be a nice small API cleanup, but this keeps real errors from getting swallowed in the meantime.
Beta Was this translation helpful? Give feedback.