在MonetDB中处理Python UDF

时间:2017-07-05 12:22:20

标签: python monetdb

在MonetDB中混合Python和SQL是将大量业务逻辑移入数据库服务器的良好开端。但是,当前的文档包含了这个游戏中新手需要采取的一些障碍。考虑以下功能:

sql>select * from getsourceattributes('tables');
+---------------+
| c             |
+===============+
| id            |
| name          |
| schema_id     |
| query         |
| type          |
| system        |
| commit_action |
| access        |
| temporary     |
+---------------+

和下表收集一些统计数据:

create table dummy(tbl string, col string, stat integer);

现在知道ptbl是一个numpy数组,我尝试了以下内容:

create function gatherStatistics(ptbl string)
returns string
language python {
     for p in ptbl:
         attr = _conn.execute("select * from getSourceAttributes('"+ str(p) +"');")
         for col in attr :
             stat = _conn.execute("select count(*) from "+ str(p) +";")
             _conn_execute("insert into dummy values('"+ str(p)+"','"+ str(col) +"',"+ str(stat)+");")
     return ptbl;
};

并使用

进行调用
select gatherstatistics('tables');
SELECT: no such table 't'
Python exception
   3.     attr = _conn.execute("select * from getSourceAttributes('"+ str(p) +"');")
   4.     for col in attr :

     5.       stat = _conn.execute("select count(*) from "+ str(p) +";")

   6.       _conn_execute("insert into dummy values('"+ str(p)+"','"+ str(col) +"',"+str(stat)+");")
   7.   return ptbl;
SQL Query Failed: ParseException:SQLparser:42S02!SELECT: no such table 't'
  • 不清楚' t'来自?
  • 什么是误解?

1 个答案:

答案 0 :(得分:0)

您遇到的问题是您将标量字符串视为数组。您调用 SELECT gatherstatistics('tables'); 并迭代 ptbl 的值。在这种情况下,您将迭代字符串'tables'的字符,第一个字符是't'字符。

如果使用列作为输入调用函数,则Python UDF中的变量将转换为(1)NumPy数组;或者(2)标量值,如果使用标量值作为输入调用函数。

考虑以下函数,它将输入参数的类型作为字符串返回:

CREATE FUNCTION get_type(s STRING)
RETURNS STRING
LANGUAGE PYTHON
{
    return str(type(s))
};

现在,如果我们使用标量值查询它,我们得到以下输出:

SELECT get_type('hello');
+------------------+
| L2               |
+==================+
| <type 'unicode'> |
+------------------+

但是如果我们用列查询它,我们得到以下输出:

SELECT get_type(name) FROM tables;
+------------------------+
| L40                    |
+========================+
| <type 'numpy.ndarray'> |
+------------------------+

通常,您将创建一个只接受一个作为给定参数的有效输入的函数。例如,您可以创建一个名为 log 的函数,该函数将数值的数组作为输入,并使用对数的标量基础。

如果要创建一个对标量值和数组值都进行操作的函数,一种简单的方法是检查输入参数的类型。如果它不是NumPy数组,我们将其转换为一个。

例如,考虑以下函数来反转字符串并对数组和标量值进行操作:

CREATE OR REPLACE FUNCTION reverse_string(s STRING)
RETURNS STRING
LANGUAGE PYTHON
{
    if not isinstance(s, numpy.ndarray):
        s = numpy.array([s])
    return [x[::-1] for x in s]
};
SELECT reverse_string('hello');
+-------+
| L2    |
+=======+
| olleh |
+-------+
SELECT reverse_string(name) FROM tables LIMIT 3;
+-----------+
| L40       |
+===========+
| samehcs   |
| sepyt     |
| snoitcnuf |
+-----------+