Python 3.4.3
,cx_Oracle 5.2 11g
,Oracle DB 11.2.0.1
您好!
我想从python到cx_Oracle
获取datapump作业的状态。
要解决此问题,我致电Oracle dbms_datapump.get_status procedure
:
DBMS_DATAPUMP.GET_STATUS(
handle IN NUMBER,
mask IN BINARY_INTEGER,
timeout IN NUMBER DEFAULT NULL,
job_state OUT VARCHAR2,
status OUT ku$_Status1120);
来自python cx_Oracle
:
get_status_params = {'handle': job_handler,
'mask': 1,
'timeout': -1,
'job_state': job_state,
'status': ??????
}
cursor.callproc('dbms_datapump.get_status', keywordParameters=get_status_params)
Oracle中的结构ku$_Status1120
:
CREATE TYPE sys.ku$_Status1120 IS OBJECT
(
mask NUMBER,
wip ku$_LogEntry1010,
job_description ku$_JobDesc1020,
job_status ku$_JobStatus1120,
error ku$_LogEntry1010
)
例如, job_status
在oracle中输入:
CREATE TYPE sys.ku$_JobStatus1120 IS OBJECT
(
job_name VARCHAR2(30),
operation VARCHAR2(30),
job_mode VARCHAR2(30),
bytes_processed NUMBER,
total_bytes NUMBER,
percent_done NUMBER,
degree NUMBER,
error_count NUMBER,
state VARCHAR2(30),
phase NUMBER,
restart_count NUMBER,
worker_status_list ku$_WorkerStatusList1120,
files ku$_DumpFileSet1010
)
如何在Python中重复Oracle类型sys.ku$_Status1120
?
答案 0 :(得分:2)
我简要介绍了如何使用cx_Oracle进行CRUD功能,在insert segment中我使用以下内容来检索返回子句的值。
new_id = cur.var(cx_Oracle.NUMBER)
statement = 'insert into cx_people(name, age, notes) values (:1, :2, :3) returning id into :4'
cur.execute(statement, ('Sandy', 31, 'I like horses', new_id))
sandy_id = new_id.getvalue()
我使用了同样的方法,其中包含来自单个值cur.var(cx_Oracle.NUMBER)
和数组cur.arrayvar(cx_Oracle.NUMBER,1000)
的处理的参数;
我没有专门使用cx_Oracle.OBJECT
类型,但我认为它与其他类型的工作方式类似。
文档:cx_Oracle.OBJECT和Variable.getvalue
试试这个
job_status_out = cursor.var(cx_Oracle.OBJECT)
get_status_params = {'handle': job_handler,
'mask': 1,
'timeout': -1,
'job_state': job_state,
'status': job_status_out
}
cursor.callproc('dbms_datapump.get_status', keywordParameters=get_status_params)
job_status = job_status_out.getvalue()
最糟糕的情况是,如果从cur.var(cx_Oracle.NUMBER)变量中获取值时遇到问题;你可以将dbms_datapump.get_status
包装在pl / sql函数中,该函数将值作为字符串返回并调用它。我知道这很有效。
答案 1 :(得分:1)
这个回答是我给出的另一个答案的替代。另一个答案是更好的解决方案,假设返回类型没有任何问题。
此解决方案适用于任何可以对数据库进行SQL调用的语言。即使您使用的应用程序语言不支持调用PL / SQL函数,您仍然可以获得所需内容。
如果您无法从Oracle数据库(例如自定义类型或复杂数据集)获取某些内容,则可以编写pipelined table function。
流水线表函数允许您在pl / sql端执行所需的任何操作,并以您选择的表格格式格式化/返回结果。
然后在应用程序层,您可以从此函数中选择,就像它是一个表。
我有a post here解释如何在NodeJS调用中使用它,但我已修改此示例以使用Python。
在PL / SQL中:
(这不是必须在一个包中,它只是我使用的例子)
/* defined in package spec */
TYPE SearchType IS RECORD (
member_id NUMBER,
dino_name VARCHAR2(400) );
TYPE SearchTypeSet IS TABLE OF SearchType;
/* defined in package body */
FUNCTION text_only(
member_id_p IN INTEGER,
search_string IN VARCHAR2)
RETURN SearchTypeSet PIPELINED
IS
retSet SearchType;
BEGIN
FOR v_rec IN (
SELECT member_id,
dino_name
FROM dd_members
WHERE contains (about_yourself,
search_string) > 0
AND member_id != member_id_p) LOOP
retSet.dino_name := v_rec.dino_name;
retSet.member_id := v_rec.member_id;
pipe ROW (retSet);
END LOOP;
RETURN;
END;
之后,它是来自应用程序的简单选择。
在Python中:
cur = con.cursor()
statement = 'SELECT member_id, dino_name FROM TABLE(text_only(:memberId, :keywords)) ORDER BY dino_name'
cur.execute(statement, (35, 'Rocks'))
res = cur.fetchall()
print (res)
对于您的特定问题,您可以将调用包含在流水线函数中,而不是使用示例中的select。