I have database with a single table Person
which has a name(str)
and age(int)
columns. So, I create simple validate function for my sqlite3.connection
def adult(age):
return age > 18
And with following code, it works fine
connection = sqlite3.connect(r'C:\Dev\Garbage\database.db')
with connection:
connection.create_function('adult', 1, adult)
cursor = connection.cursor()
persons = cursor.execute('select "p"."name", "p"."age" from "Person" "p" where adult("p"."age")').fetchall()
for person in persons:
print(person)
But if I change adult
like this
def adult(age):
return 1 / 0
I will get sqlite3.OperationalError: user-defined function raised exception
.
In my project, it might be a huge amount of functions and I'd like to know - is there any way to know which function raised an exception? Or get ZeroDivisionError: division by zero
instead of this.
Python's sqlite3
module throws away any error information from the exception, and replaces it with the constant message you've seen:
void _pysqlite_func_callback(sqlite3_context* context, int argc, sqlite3_value** argv)
{
...
py_func = (PyObject*)sqlite3_user_data(context);
args = _pysqlite_build_py_params(context, argc, argv);
if (args) {
py_retval = PyObject_CallObject(py_func, args);
Py_DECREF(args);
}
ok = 0;
if (py_retval) {
ok = _pysqlite_set_result(context, py_retval) == 0;
Py_DECREF(py_retval);
}
if (!ok) {
if (_enable_callback_tracebacks) {
PyErr_Print();
} else {
PyErr_Clear();
}
sqlite3_result_error(context, "user-defined function raised exception", -1);
}
...
}
I don't know what prevents it from appending the exception message to the returned error message.
Anyway, it is possible to print out the inner stack trace by calling enable_callback_tracebacks:
import sqlite3
db = sqlite3.connect(':memory:')
def error():
raise Exception('hello')
db.create_function('error', 0, error)
sqlite3.enable_callback_tracebacks(True) # <-- !
db.execute('select error()')
Traceback (most recent call last): File "<stdin>", line 1, in error Exception: hello Traceback (most recent call last): File "<stdin>", line 1, in sqlite3.OperationalError: user-defined function raised exception
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With