Проблема с запросом куста при попытке вычислить результаты Python UDF - PullRequest
0 голосов
/ 01 февраля 2019

Я новичок в Python и UDF Python, хотел бы изучить эти концепции.

Я написал запрос в oracle, который выведет список простых чисел от 1 до 100.

Запрос-

with hundred(n1) as
(
    select 1 from dual
    union all
    select 1+n1 from hundred where n1<100
),
 modresult as (select t1.n1 as n1, t2.n1 as n2
,case when mod(t1.n1,t2.n1)=0 then 1 else 0 end as modresult
from hundred t1 join hundred t2 on t1.n1>t2.n1
and t2.n1 <>1) 
  select 2 n1 from dual
  union all
  select distinct modresult.n1 from modresult where modresult.n1 not in
  (select distinct modresult.n1 from modresult where modresult<>0) order by 1;

Я хочу повторить то же самое в улье, так как куст не поддерживает рекурсивные запросы, я написал простой скрипт на python, который будет печатать числа на основе ввода.

Моя идея былаиспользовать результат в качестве таблицы CTE и затем вычислять дальнейшие запросы.

Python Script -

[prjai@lnx0689 py_ws]$ cat prime_num.py
import sys

try:
        for line in sys.stdin:
                num = int(line)
                for i in range(1, num+1):
                        print u"%i".encode('utf-8') %(i)
except:
        print sys.exc_info()

Добавить файл в Hive ENV -

add FILE /home/prjai/prvys/py_ws/prime_num.py

Попробовал ниже-

Ниже набор запросов работает без каких-либо проблем -

with t1 as (select transform(10) using 'python prime_num.py' as num1) select num1 from t1;
OK
1
2
3
4
5
6
7
8
9
10

>

with t1 as (select transform(10) using 'python prime_num.py' as num1) select num1 from t1 union all select num1 from t1;
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10

Но когда япопытаться выполнить некоторые операции, кроме объединения, на результирующем наборе, это не удается, я попытался найти альтернативу, когда каждый из приведенных ниже запросов не удался, так как я не был уверен, в чем проблема.Пожалуйста, найдите ниже

hive> with t1 as (select transform(10) using 'python prime_num.py' as num1) select t1.num1 from t1 join t1 t2 on t1.num1=t2.num1;

hive> with t1 as (select transform(10) using 'python prime_num.py' as num1), t2 as (select transform(10) using 'python prime_num.py' as num2) select * from t1,t2 where t1.num1<t1.num2;

with t1 as (select transform(10) using 'python prime_num.py' as num1), t2 as (select transform(10) using 'python prime_num.py' as num2) select * from t1,t2 where cast(t1.num1 as int)<cast(t2.num2 as int);

 with t1 as (select transform(10) using 'python prime_num.py' as num1), t2 as (select transform(10) using 'python prime_num.py' as num2) select * from t1,t2;

Ошибка для всех вышеупомянутых запросов -

org.apache.hadoop.hive.ql.metadata.HiveException: [Error 20003]: An error occurred when trying to close the Operator running your custom script.
        at org.apache.hadoop.hive.ql.exec.ScriptOperator.close(ScriptOperator.java:585)
        at org.apache.hadoop.hive.ql.exec.Operator.close(Operator.java:697)
        at org.apache.hadoop.hive.ql.exec.Operator.close(Operator.java:697)
        at org.apache.hadoop.hive.ql.exec.mr.MapredLocalTask.startForward(MapredLocalTask.java:452)
        at org.apache.hadoop.hive.ql.exec.mr.MapredLocalTask.startForward(MapredLocalTask.java:418)
        at org.apache.hadoop.hive.ql.exec.mr.MapredLocalTask.executeInProcess(MapredLocalTask.java:384)
        at org.apache.hadoop.hive.ql.exec.mr.MapredLocalTask.execute(MapredLocalTask.java:153)
        at org.apache.hadoop.hive.ql.exec.Task.executeTask(Task.java:197)
        at org.apache.hadoop.hive.ql.exec.TaskRunner.runSequential(TaskRunner.java:100)
        at org.apache.hadoop.hive.ql.Driver.launchTask(Driver.java:2074)
        at org.apache.hadoop.hive.ql.Driver.execute(Driver.java:1745)
        at org.apache.hadoop.hive.ql.Driver.runInternal(Driver.java:1454)
        at org.apache.hadoop.hive.ql.Driver.run(Driver.java:1172)
        at org.apache.hadoop.hive.ql.Driver.run(Driver.java:1162)
        at org.apache.hadoop.hive.cli.CliDriver.processLocalCmd(CliDriver.java:234)
        at org.apache.hadoop.hive.cli.CliDriver.processCmd(CliDriver.java:185)
        at org.apache.hadoop.hive.cli.CliDriver.processLine(CliDriver.java:401)
        at org.apache.hadoop.hive.cli.CliDriver.executeDriver(CliDriver.java:791)
        at org.apache.hadoop.hive.cli.CliDriver.run(CliDriver.java:729)
        at org.apache.hadoop.hive.cli.CliDriver.run(CliDriver.java:652)
        at org.apache.hadoop.hive.cli.CliDriver.main(CliDriver.java:647)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.hadoop.util.RunJar.run(RunJar.java:221)
        at org.apache.hadoop.util.RunJar.main(RunJar.java:136)

Не могли бы вы помочь мне в отладке проблемы, я делаю что-то здесь неправильно.

PS - Возможно, есть и другое решение, но хотелось бы понять, есть ли проблема с вышеуказанным подходом

В качестве обходного пути я создал временную таблицу и написал запрос для поиска простых чисел.

hive> create temporary table t1 as with t1 as (select transform(10) using 'python prime_num.py' as num1) select * from t1;

with ten as (select num1 as c1 from t1),  
modresult as (select t1.c1 as c1, t2.c1 as n2
,case when pmod(t1.c1,t2.c1)=0 then 1 else 0 end as c3
from ten t1, ten t2 where  t1.c1>t2.c1
and t2.c1 <>1)
select 2 c1
union all
select distinct int(m1.c1) from modresult m1
left outer join (select distinct c1 from modresult where c3<>0) m2 on m1.c1=m2.c1 where m2.c1 is null;
...