2017-07-05 49 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 | 
+-----------+