我可以用Python为MySQL编写UDF吗?
我想要一个选项,可以通过MySQL的存储过程来调用Python。
所以我在想,是否可以用Python写一个用户定义的函数(UDF),然后从MySQL中调用它。
如果这样做不行,那还有什么其他方法可以实现这个功能呢?
1 个回答
7
MySQL 5.0的文档提到,触发器可以调用用户定义的函数(UDF),所以这一点是可行的。查看一些UDF扩展的源代码,可以让你了解其中的复杂性。你可以在MySQL UDF库找到开源的包。
我希望能给出一个简单的答案,关于“如何用Python创建MySQL UDF”,但我不知道有什么现成的简单方法可以做到这一点。
Postgres有一种PL/Python语言,可以让你直接在数据库中用Python编写过程和函数。这段代码可能是将Python与MySQL结合的最佳指南;不过,据我所知,目前还没有人做到这一点(但我希望我错了)。
关于如何实现这一点的一些复杂细节:
UDF是共享对象,会被加载到MySQL的后台程序中,所以要创建一个UDF,你需要生成C语言的代码,这些代码需要做几件事:初始化Python解释器,加载并编译你的Python脚本为字节码,然后把MySQL UDF的参数转换成Python函数调用,最后再把返回值转换回来。
对于一个简单的名为myfunc
的UDF字符串函数,这个共享对象会包含以下函数:
// initialize state when 'myfunc' is loaded.
my_bool myfunc_init(UDF_INIT *initid, UDF_ARGS *args, ...)
// call myfunc, this would need to translate the args, invoke the
// python function, then return the string, may need to create and cache
// python sub-interpreters on the fly, etc
char *myfunc(UDF_INIT *initid, UDF_ARGS *args, ...)
// clean up the state when 'myfunc' is unloaded.
void myfunc_deinit(UDF_INIT *initid);
因为可能会有多个线程同时调用你的UDF,所以你需要找到一种方法,要么在单个函数调用的上下文中高效地创建和缓存子解释器,要么安全地在多个线程之间重用一个解释器(这可能会因为加锁而导致速度变慢,令人无法接受)。