Я новичок в 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;