Oracle에서 Python 호출
오라클 프로시저 내에서 파이썬을 호출할 수 있습니까?저는 역 사례(Python에서 Oracle SQL로 호출)에 대한 많은 문헌을 읽었지만 그 반대는 아닙니다.
제가 하고 싶은 일은 Oracle이 데이터베이스 테이블을 생성하도록 한 다음 Python을 호출하여 DataFrame으로 이 데이터베이스 테이블을 전달하여 Python을 사용하여 무언가를 수행하고 결과를 생성할 수 있도록 하는 것입니다.Oracle 절차 중에 Python을 여러 번 호출해야 할 수도 있습니다.이것이 가능한지 그리고 어떻게 할 수 있는지 아는 사람?
가장자리에는 PL/SQL 제한을 극복하는 방법에 대한 가능성이 있습니다.Database와 Python 프로그램 간의 특정 인터페이스를 설계할 수 있습니다.인터넷에서 데이터를 얻기 위해 파이썬의 라이브러리 중 하나를 사용할 것이라고 생각합니다.그런 다음 C 라이브러리를 사용하여 오라클과 데이터를 교환합니다.
c 라이브러리를 사용하여 python 호출 -> 데이터 파일 -> 외부 테이블 -> 데이터
주의: 개념 증명 또는 보다 심층적인 탐색을 위한 출발점으로 간주합니다.또한 생산에 사용하는 것을 강력히 권장합니다.시스템 프로그램을 호출하기 위해 PL/SQL 감옥을 깨는 것은 적어도 안전하지 않은 것으로 간주될 수 있습니다.
다음은 진행 방법에 대한 가능한 방법입니다.
필수 구성 요소 ==--
pip 설치 quandl
quandl.py ==--
#!/usr/bin/python
import quandl
# World Bank Education Statistics
# Population, tertiary, total - Czech Republic
data = quandl.get("WEDU/CZE_SP_TER_TOTL_IN")
data.to_csv("/u01/data/data.txt")
exec.c ==--
//
// gcc -Wall -fPIC -c exec.c
// gcc -shared -o exec.so exec.o
// mkdir -p /u01/lib
// cp exec.so /u01/lib
//
#include <stdlib.h>
int execute() {
system("/u01/bin/get_data.py");
return 0; // We want to make the compiler happy
}
수신기 구성 ==--
SID_LIST_LISTENER =
...
(SID_DESC =
...
(ENVS="EXTPROC_DLLS=ANY")
(PROGRAM = extproc)
...
DDL 파트 ==--
create or replace library c_exec is '/u01/lib/exec.so';
create or replace procedure exec as external
name "execute"
library c_exec
language c;
/
create directory pydata as '/u01/data';
create table data (
"date" varchar2(14),
"value" varchar2(32)
) organization external (
type oracle_loader
default directory pydata
access parameters (
records delimited by newline
nobadfile nodiscardfile nologfile
fields terminated by ','
) location (pydata:'data.txt')
);
용도 ===---
== 처리를 위한 데이터 다운로드--
외부 PL/SQL C 라이브러리 사용 결과를 외부 테이블의 예상 위치에 저장하는 파이썬 프로그램을 호출합니다.
execute exec;
데이터 쿼리 ==--
select
to_date("date",'yyyy-mm-dd') "date",
to_number("value") "value"
from data
where "date" != 'Date';
결과 ==--
date value
--------- ----------
31-DEC-70 886414
31-DEC-71 885549
31-DEC-72 877533
31-DEC-73 862859
저장 프로시저를 Java로 작성할 수 있고 Java를 사용하여 파이썬 코드를 실행할 수 있으므로 두 가지를 결합하여 원하는 작업을 수행할 수 있습니다.
글쎄요, 아주 좋은 선택지들과 함께 많은 다른 답들이 있습니다. 하지만 다른 것을 제안해 보겠습니다.
이 시나리오를 상상해 보겠습니다.
- 당신이 데이터 프레임을 언급한 바와 같이, 나는 다른 방식으로 데이터와 상호 작용하는 파이썬 프로그램 세트를 가지고 있습니다.
- 런타임 중에 python 스크립트를 실행해야 하는 큰 Oracle 프로시저가 있으므로 기본적으로 Oracle PL/SQL 내부에서 Python을 사용해야 합니다. 외부 라이브러리나 Java 코드(이미 제공된 예제)를 사용하지 않는 한 불가능합니다.
할 수 은 항상 것은셸스호것다에서 입니다.PL/SQL
API DBMS_SCHEDULER
이러한 셸 스크립트는 원하는 대로 호출할 수 있습니다. 이 경우 Python 프로그램입니다.
제 시나리오는 다음과 같습니다.
- sys_refcursor 변수의 결과 집합을 가져오는 함수를 실행하는 하나의 Python 프로그램.
- 일반 셸 스크립트로 이러한 파이썬 프로그램을 호출하는 하나의 오라클 프로시저
잘 해내자꾸나
SQL> create table t_python ( c1 number generated by default on null as identity ( start with 1 increment by 1 ) ,
c2 varchar2(10) ,
c3 date
) ;
Table created.
SQL> declare
begin
for r in 1..10
loop
insert into t_python values ( null , dbms_random.string('A','5') , sysdate - round(dbms_random.value(1,100),0) );
commit ;
end loop;
end;
/
PL/SQL procedure successfully completed.
SQL> select * from t_python
2 ;
C1 C2 C3
---------- ---------- ---------
1 Anrio 14-JUL-20
2 ouaTA 04-MAY-20
3 Swteu 06-JUL-20
4 kdsiZ 24-MAY-20
5 PXxbS 14-MAY-20
6 xQFYY 18-JUN-20
7 oahQR 09-MAY-20
8 ZjfXw 24-MAY-20
9 AmMOa 26-JUL-20
10 IQKpK 25-JUL-20
10 rows selected.
SQL>
그래서, 제가 데이터베이스에 다음을 반환하는 함수를 반환된다고 가정해 보겠습니다.SYS_REFCURSOR
개체, 즉 컬렉션 또는 데이터 집합입니다.
SQL> CREATE OR REPLACE FUNCTION get_result_table_f RETURN SYS_REFCURSOR
AS
r_python SYS_REFCURSOR;
BEGIN
OPEN r_python FOR
SELECT
c1,
c2,
c3
FROM
t_python
ORDER BY
c1,
c2,
c3;
RETURN r_python;
END;
/
Function created
제 파이썬 프로그램으로 이 기능을 호출하면 완벽하게 작동합니다.
import cx_Oracle
import pandas as pd
conn = cx_Oracle.connect('user/pwd@hostname:port/servicename')
cur = conn.cursor()
refCursor = cur.callfunc('get_result_table_f', cx_Oracle.CURSOR, [])
for row in refCursor:
print(row)
Result
$ /usr/bin/python3.6 /home/myuser/testcursor.py
(1, 'Anrio', datetime.datetime(2020, 7, 14, 12, 38, 52))
(2, 'ouaTA', datetime.datetime(2020, 5, 4, 12, 38, 52))
(3, 'Swteu', datetime.datetime(2020, 7, 6, 12, 38, 52))
(4, 'kdsiZ', datetime.datetime(2020, 5, 24, 12, 38, 52))
(5, 'PXxbS', datetime.datetime(2020, 5, 14, 12, 38, 52))
(6, 'xQFYY', datetime.datetime(2020, 6, 18, 12, 38, 52))
(7, 'oahQR', datetime.datetime(2020, 5, 9, 12, 38, 52))
(8, 'ZjfXw', datetime.datetime(2020, 5, 24, 12, 38, 52))
(9, 'AmMOa', datetime.datetime(2020, 7, 26, 12, 38, 52))
(10, 'IQKpK', datetime.datetime(2020, 7, 25, 12, 38, 52))
그렇다면 오라클 프로시저 내에서 이 파이썬 프로그램을 어떻게 부를 수 있을까요?
제 옵션은 DBMS_Scheduler의 API를 사용하는 것인데, 이 API는 python 프로그램을 호출하기 위해 셸 스크립트만 필요합니다.를 DBMS_SCHEDULER
당신은 다음만 하면 됩니다.
- 스케줄러가 셸을 실행하는 데 사용할 자격 증명을 만듭니다.OS 사용자여야 합니다(아래 예제에서는 ftpcpl).
- 스케줄러 작업 유형 EXTERNAL SCRIPT 사용
- 셸 스크립트를 사용하여 python 프로그램을 호출합니다(python 스크립트는 데이터베이스와 동일한 서버에 있어야 합니다).다른 서버에서 수행할 수 있는 옵션이 있습니까? 하지만 Oracle 스케줄러 에이전트를 설치해야 하기 때문에 더 복잡합니다.)
이런 식으로 보여야 합니다.
create or replace procedure run_python_program
as
v_job_count pls_integer;
v_owner varchar2(30);
v_job varchar2(120) := 'MY_PYTHON_SCRIPT';
begin
select count(*) into v_job_count from dba_scheduler_jobs where job_name = v_job ;
if v_job_count > 0
then
DBMS_SCHEDULER.drop_job (job_name=> v_job , force => true);
end if;
DBMS_SCHEDULER.create_job
(
job_name => v_job,
job_type => 'EXTERNAL_SCRIPT',
job_action => '/home/myuser/my_shell_script.sh `date +%Y%m%d`',
credential_name => 'ftpcpl',
enabled => FALSE
);
DBMS_SCHEDULER.run_job (job_name=> v_job, use_current_session => true);
exception when others then raise;
end;
/
당신은 보이는 것처럼 쉬운 대본을 가지고 있습니다.
#/bin/bash
odate=$1
logfile=/home/myuser/logfile_$odate.txt
/usr/bin/python3.6 /home/myuser/testpython.py >> $logfile
절차 실행
SQL> begin
run_python_program;
end;
/
PL/SQL procedure successfully completed.
SQL> host cat /home/test/logfile_20200809.txt
(1, 'Anrio', datetime.datetime(2020, 7, 14, 12, 38, 52))
(2, 'ouaTA', datetime.datetime(2020, 5, 4, 12, 38, 52))
(3, 'Swteu', datetime.datetime(2020, 7, 6, 12, 38, 52))
(4, 'kdsiZ', datetime.datetime(2020, 5, 24, 12, 38, 52))
(5, 'PXxbS', datetime.datetime(2020, 5, 14, 12, 38, 52))
(6, 'xQFYY', datetime.datetime(2020, 6, 18, 12, 38, 52))
(7, 'oahQR', datetime.datetime(2020, 5, 9, 12, 38, 52))
(8, 'ZjfXw', datetime.datetime(2020, 5, 24, 12, 38, 52))
(9, 'AmMOa', datetime.datetime(2020, 7, 26, 12, 38, 52))
(10, 'IQKpK', datetime.datetime(2020, 7, 25, 12, 38, 52))
요약
PL/SQL에서 python(셸 스크립트에 내장된)을 호출하는 방법을 보여주기 위해 매우 쉽고 간단한 테스트를 수행했습니다.실제로 여러 외부 스크립트(파이썬 프로그램)를 실행하는 절차를 만들 수 있으며 여러 가지 방법으로 데이터와 상호 작용할 수 있습니다.
예를 들어 다음 작업을 수행할 수 있습니다.
- 오라클의 프로시저는 데이터를 생성하고 이 데이터를 테이블, 컬렉션 또는 sys_refcursor 개체에 저장합니다.DBMS_Scheduler EXTERNAL_SCRIPT 작업 유형을 사용하여 PL/SQL 내의 python 프로그램을 호출하고 데이터와 상호 작용할 수 있습니다.
- 파이썬은 원본 데이터 집합에서 출력 데이터를 생성합니다.Python 프로그램에 테이블을 로드하거나 절차에서 다시 읽을 수 있는 외부 테이블로 CSV를 남길 수 있습니다.
등등.
저는 실제로 Oracle Scheduler Chains를 사용하여 단계별로 실행되는 셸 스크립트의 많은 프로그램을 가지고 있습니다.그 단계들 중 하나는 사실 파이썬 프로그램입니다.『API』의.DBMS_SCHEDULER
셸 스크립트(또는 윈도우즈의 cmd)를 사용하여 호출할 수 있는 경우 PL/SQL에서 기술을 실행해야 할 때 매우 유용합니다.
Python 스크립트를 호출하여 외부 테이블을 데이터로 채울 수 있는 Preprocessor 기능을 외부 테이블과 함께 사용할 수 있습니다.예제는 OTN 문서 https://community.oracle.com/docs/DOC-994731 의 외부 테이블 사용 섹션에서 확인할 수 있습니다.
파이썬을 사용하려는 컨텍스트에 따라 OML4Py를 고려할 수 있습니다.
주요 이점:
데이터베이스 내 처리: "데이터가 아닌 알고리즘을 이동합니다!"—데이터가 상주하는 위치에서 데이터를 처리하여 데이터 이동을 없애고 병렬 분산 알고리즘을 사용하는 고성능 컴퓨팅 엔진으로 오라클 환경을 더욱 활용할 수 있습니다.
신속한 머신 러닝 애플리케이션 구축—데이터베이스 내 머신 러닝 모델은 기본 SQL 기능이기 때문에 SQL 및 R 스크립트를 통해 모델을 즉시 구축할 수 있습니다.
자세한 내용:
Oracle 머신러닝: 엔터프라이즈용 R 및 Python 확장
슬라이드(이 질문에 대한 답변):
- 7페이지: 데이터 액세스, 분석 및 탐색
- 24페이지: SQL에서 사용자 정의 함수 생성(또는 R/Python에서 사용)
- 25페이지: SQL에서 사용자 정의 함수 호출
PL/SQL은 Oracle 서버 내에서 신속하게 실행할 수 있도록 특별히 설계되었으며 내부 제한으로 인해 다른 공급업체의 임의 코드가 가능한 곳이 아니기 때문에 이것은 직접적으로 불가능하다고 생각합니다.
OTOH TCP 채널을 통해 저장 프로시저에서 다른 서버와 상호 작용할 수 있습니다. 이 페이지는 UTL_TCP 패키지를 참조합니다.외부 네트워크 서버에서는 모든 언어와 논리를 사용할 수 있습니다.
좀 복잡하지만 가능성이 있습니다.저는 그것을 한 번 본 적이 있습니다.당신은 해야 합니다.
- Oracle 데이터베이스 내에 java 클래스를 만듭니다.이 클래스는 이 파일을 포함하는 디렉토리의 .py 파일을 호출합니다.
- 항목 1의 java 클래스를 호출하는 프로시저를 만듭니다.
- SQL 쿼리에서 필요할 때마다 항목 2의 프로시저를 호출합니다.
언급URL : https://stackoverflow.com/questions/22564503/calling-python-from-oracle
'it-source' 카테고리의 다른 글
소스에 X개의 요소가 있지만 대상에는 1개만 허용됩니다. (0) | 2023.06.30 |
---|---|
Firestore 배열 필드에 값 추가 (0) | 2023.06.30 |
Gitrebase - 모든 병합 충돌이 해결된 경우에도 계속 불만 제기 (0) | 2023.06.30 |
sql server 그룹에서 첫 번째 행 선택 (0) | 2023.06.25 |
속성 선언의 "new" 키워드(c#) (0) | 2023.06.25 |