Is it possible to call Python within an Oracle procedure? I\'ve read plenty of literature about the reverse case (calling Oracle SQL from Python), but not the other way around.<
On the edge there is a possibility on how to overcome the PL/SQL limitations. You can design a specific interface between Database and Python program. I suppose You'd use one of the Python's library to get some data from the Net. And then exchange it's data with Oracle using the C Library.
call python using c library -> data file -> external table -> data
NOTICE: Take it as a proof of concept or rather starting point for deeper exploration. Also I'd strongly discourage You from using it on production. Breaking the PL/SQL jail to call system program could be considered at least as unsafe.
So this is the possible way on how to proceed:
--== Prerequisities ==--
pip install 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
int execute() {
system("/u01/bin/get_data.py");
return 0; // We want to make the compiler happy
}
--== LISTENER CONFIGURATION ==--
SID_LIST_LISTENER =
...
(SID_DESC =
...
(ENVS="EXTPROC_DLLS=ANY")
(PROGRAM = extproc)
...
--== DDL PART ==--
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')
);
---=== USAGE ===---
--== DOWNLOAD DATA FOR PROCESSING ==--
Using the external PL/SQL C library You would call the python program that stores the result to the expected location for the external table.
execute exec;
--== QUERY THE DATA ==--
select
to_date("date",'yyyy-mm-dd') "date",
to_number("value") "value"
from data
where "date" != 'Date';
--== RESULT ==--
date value
--------- ----------
31-DEC-70 886414
31-DEC-71 885549
31-DEC-72 877533
31-DEC-73 862859