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( param1 in varchar2, param2 in varchar2, param3 out varchar2) as .....La llamada sería
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.
No hay comentarios:
Publicar un comentario