Skip to content

Python UDF的创建、使用和删除过程

watch2bear edited this page Mar 5, 2024 · 8 revisions

完成Python UDF Metadata Management的更新后,目前使用和测试Python UDF不必要重新进行OB的编译,而是通过SQL语句在系统内完成创建和使用。

以下三个部分将展示Python UDF在创建、使用和删除时所需要使用的SQL语法,及相应实现效果。

现已实现了对OceanBase Python UDF元信息系统表的自动创建,无需在oceanbase数据库下手动创建。 如果显示该表不存在,则需要使用obd命令重新部署OceanBase server。

obd cluster redeploy $cluster_name 

Python UDF的创建

创建Python UDF的SQL语法与创建存储过程或普通UDF的语法比较类似:

CREATE PYTHON_UDF $udf_name ($arg $arg_type, ...) RETURNS $ret_type { $python_code }; 

目前的arg type与ret type支持STRING, INTEGER, REAL三种类型,分别为字符串、整数与浮点数。

在Python代码中需要指定pyinitial函数与pyfun函数

pyinitial代表了对函数计算过程中所反复使用到的上下文变量的初始化过程,包括模型加载过程等

而pyfun则代表具体的计算过程,其中使用到pyinitial中声明的变量

其中pyfun的参数是numpy数组,代表某一列的参数,这利用了批量计算加速查询过程,因此编写函数时需要注意对数组的操作。

以下是一个创建Python UDF的示例:

CREATE PYTHON_UDF test_efficiency(arg INTEGER) RETURNS INTEGER {"import numpy as np
\nimport time
\ndef pyinitial():
\n\tpass
\ndef pyfun(arg):
\n\tstart = time.process_time()
\n\tm1 = np.random.randint(0,10,(100,100))
\n\tm2 = np.random.randint(0,10,(100,100))
\n\tnp.matmul(m1, m2)
\n\tfinish = time.process_time()
\n\twith open('/home/test/log/expedia/python_log', 'a') as f:
\n\t\tf.write('ms:{0}\\r\\n'.format(1000 * (finish - start)))
\n\t\tf.close()
\n\treturn arg\0" };

无文件写入版本

CREATE PYTHON_UDF test_efficiency(arg INTEGER) RETURNS INTEGER {"import numpy as np
\ndef pyinitial():
\n\tpass
\ndef pyfun(*args):
\n\tm1 = np.random.randint(0,10,(100,100))
\n\tm2 = np.random.randint(0,10,(100,100))
\n\tnp.matmul(m1, m2)
\n\treturn args[0]\0" };

此处使用了\n \t \0,明确Python代码间的换行与缩进,以及指定字符串末尾。

(现版本测试发现OceanBase能正确处理换行与Tab缩进,无需手动写\n \t)

目前尚未实现对Python Code的检查过程,因此在编写时需要注意正确性。

Python UDF的使用

使用Python UDF的过程与使用普通UDF或内建函数是比较相似的,区别在于使用PREDICT作为关键字,声明目前使用是Python UDF。

以下是一个使用Python UDF的示例,设定expedia_data_q1为一个已经存在的表,其中srch_saturday_night_bool是表中的INTEGER列:

SELECT srch_id, prop_id, PREDICT test_efficiency(srch_saturday_night_bool) AS testing FROM expedia_data_q1;

使用过程中需要注意的是,PREDICT已经作为关键字被使用,因此列名、别名和表面需避免使用PREDICT。

Python UDF的删除

删除Python UDF的语法与删除普通UDF、删除表类似:

DROP PYTHON_UDF test_efficiency;

该SQL将之前创建的Python UDF 'test_efficiency'删除。