我有一个包含Person
和name(str)
列的单个表age(int)
的数据库。因此,我为sqlite3.connection
def adult(age):
return age > 18
使用以下代码,它可以正常工作
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)
但如果我像这样更改adult
def adult(age):
return 1 / 0
我会得到sqlite3.OperationalError: user-defined function raised exception
。
在我的项目中,它可能是一个庞大的函数,我想知道 - 有没有办法知道哪个函数引发了异常?或者获取ZeroDivisionError: division by zero
而不是此。
答案 0 :(得分:3)
Python的sqlite3
模块抛弃异常中的任何错误信息,并将其替换为您看到的常量消息:
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);
}
...
}
我不知道是什么阻止它将异常消息附加到返回的错误消息。
无论如何,可以通过调用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