2017-07-05 52 views
0

在MonetDB中混合使用Python和SQL是将大量业务逻辑移入数据库服务器的一个很好的开始。然而,目前的文档包含了一些新手在这个游戏中需要承担的一些障碍。考虑下面的函数:在MonetDB中处理Python UDF

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'来自哪里?
  • 什么是误解?

回答

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 | 
+-----------+