Teniendo esto claro, se trata de diseñar una estrategia que nos permita usar toda la potencia de los procedimientos almacenados con el mínimo coste en caso de cambiar de gestor de base de datos.
He intentado alejarme del estándar lo menos posible pero, como he comentado, no veo forma de librarse del uso directo de cx_Oracle. Esto es debido a las particularidades que presenta cada gestor a la hora de reservar espacio para las variables de salida en función del tipo. Por ello, lo que he hecho es escribir una función para cada tipo de parámetro de salida, por ejemplo,
from django.db import connection
import cx_Oracle
def call_proc_str1(cadena, valors=None):
""" llama a un procedimiento Oracle cuyo ultimo parámetro es un string de salida """ cur = connection.cursor()
# preparam cadena per a Oracle
cadena="BEGIN %s; END;;" % (cadena,)
# preparam el parametre de sortida
sortida=cur.cursor.var(cx_Oracle.STRING)
# afeixim paràmetre com a darrer
valors.append(sortida)
try:
cur.execute(cadena, valors)
# retornam paràmetre de sortida
return sortida.getvalue()
except Exception, e:
mensaje="%s Error: call_proc cadena#%s valors#%s" % (e, cadena, valors)
logger.error(mensaje)
raise Exception(mensaje)
finally:
cur.close()
Se observan varios detalles:
- Hay que formar la cadena de la llamada como cadena="BEGIN %s; END;;" % (cadena,). Es debido a la forma cómo se hace la llamada via execute.
- Se crea y se reserva espacio para un string mediante cur.cursor.var(cx_Oracle.STRING) y se añade al final de los parámetros de conexión.
- Extraemos el valor del parámetro mediante sortida.getvalue()
Para un procedimiento como este:
create or replace procedure prueba(La llamada sería
param1 in varchar2,
param2 in varchar2,
param3 out varchar2) as .....
try:
plsql="prueba(%s, %s, %s)"
param3=call_proc_str1(plsql, [param1, param2])
return jOk(param3)
except Exception, ex:
return jErr(str(ex))
Notar que usamos el placeholder %s de python-db en vez de el de Oracle.
En resumen; No es la mejor solución del mundo pero es fácil de portar si cambiamos de gestor de base de datos.