MANEJO DE EXCEPCIONES CON POSTGRESQL

1,838 views
Skip to first unread message

Edgar De La Cruz

unread,
Oct 27, 2015, 3:44:22 PM10/27/15
to Django-es
Lo que hago es llamar un función postgresql en django, lo cual yo logro llamarla, hago un recorrido en django y por cada objeto voy llamando a la función para que se realice un calculo y una inserción en otra tabla, pero quiero cachar las excepciones en caso de que un dato del objeto que se recorra este mal, como lo es el error violates foreign key constraint para que pueda realizar un delete e impedir que sigan insertándose mas datos. soy nuevo en postgres mi función es básica. la dejo por aqui. saludos.

SELECT calculo_honorario_prueba_edgar(11400,330,16,183,53453,1,2,8554,1845,'honorarios',TRUE ,0);

CREATE OR REPLACE FUNCTION calculo_honorario_prueba_edgar(monto       NUMERIC, unidad_id INTEGER, quincena_id INTEGER, proyecto_id INTEGER, empleado_id INTEGER, usuario_id INTEGER,
                                                          tipo_nomina INTEGER, pagador INTEGER, object_id INTEGER, tabla TEXT, insertar BOOLEAN, calc_temp_id INTEGER)
  RETURNS TEXT AS
  $BODY$
  DECLARE
    mensaje     TEXT;
    id_new      INT;
    calculo_isr DECIMAL;
    sueldo_grav DECIMAL;
    sueldo_liq  DECIMAL;
    concepto    JSON;
    ins         BOOLEAN;
    user_id     INTEGER;
  BEGIN
    calculo_isr :=(SELECT calcular_isr($1));
    sueldo_grav := $1 / 2;
    sueldo_liq := ROUND(sueldo_grav - calculo_isr, 2);
    concepto :='{"nombre":"sueldo","monto":"' || ROUND(sueldo_liq, 2) || '","tipo":1}';
    ins:= $11;
    calc_temp_id := $12;
    user_id =$6;

    IF ins = TRUE
    THEN
      BEGIN
        id_new := (SELECT CASE WHEN max(id) NOTNULL
          THEN max(id) + 1
                          ELSE 1 END
                   FROM calculonomina_periodo_calculo_temp);
        EXECUTE
        'INSERT INTO calculonomina_periodo_calculo_temp VALUES (' || id_new || ',' || $2 || ',' || calculo_isr || ',' || round(sueldo_grav, 2) || ',' || sueldo_liq || ',NULL,' || $3 ||
        ',NULL,NULL,' || $4 || ',''' || concepto || ''',' || $5 || ',NULL,' || $6 || ',' || $7 || ',' || $8 || ',' || $9 || ',''HONORARIOS'');';
        IF FOUND
        THEN
          mensaje = 'Error al insertar un procedimiento';
        --                         EXECUTE 'DELETE FROM calculonomina_periodo_calculo_temp
        --                         WHERE usuario_id ='||user_id||'AND tabla ='||'''HONORARIOS;''';
        ELSE
          mensaje = 'Se ha registrado correctamente la informacion';
        END IF;
      END;
    ELSE
      BEGIN
        id_new = calc_temp_id;
        UPDATE calculonomina_periodo_calculo_temp
        SET id        = calc_temp_id, isr = calculo_isr, sueldo_gravable = round(sueldo_grav, 2), sueldo_liquido = sueldo_liq,
          subsidio    = NULL, quincena = $3, cat_proyecto_id = $4, conceptos_pago = concepto,
          empleado_id = $5, tipo_plaza_id = NULL, usuario_id = $6, tipo_nomina = $7, cat_pagador_id = $8, objecto_id = $9,
          tabla       = 'HONORARIOS'
        WHERE id = calc_temp_id;

        IF FOUND
        THEN
          mensaje = 'Error al insertar un procedimiento';
          EXECUTE 'DELETE FROM calculonomina_periodo_calculo_temp
                        WHERE usuario_id =' || user_id || 'AND tabla =' || '''HONORARIOS;''';
        ELSE
          mensaje = 'Se ha registrado correctamente la informacion';
        END IF;
      END;
    END IF;

    RETURN mensaje;
  END;
  $BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

Javier Sanchez Toledano

unread,
Oct 27, 2015, 4:02:30 PM10/27/15
to djan...@googlegroups.com
Aqui puedes consultar las excepciones que puedes "cachar".

Javier Sanchez Toledano
Auditor Líder ISO 9001 // Desarrollo Web Python+Django
js.to...@me.com

Cornelio Royer Climent

unread,
Oct 28, 2015, 11:22:15 AM10/28/15
to Django-es
Hola Edgar

Por lo que veo estas haciendo un programa de nomina en django. 

Yo tambien requiero hacer un sistema de nomina en django.

Me podrias compartir lo que has hecho?

Yo pudiera contribuir a su desarrollo.

En que pais estas?


saludos.....

Edgar De La Cruz

unread,
Nov 10, 2015, 12:26:39 PM11/10/15
to Django-es
Hola, gracias por el link, efectivamente logre atrapar la excepción del lado de django, lo que no he podido atrapar es la excepción del lado de la base de datos como lo es en el caso de mi funcion, he logrado atrapar excepciones como el not null, y otros pero no el violates foreign key constraint , no entra en ninguna excepción, entiendo que este grupo es de django pero si tengo ese problema y pues ojala y puedan ayudarme, ahora por la otra parte en mi funcion django en la que hago el recorrido e invoco a la función postgres, estoy pensando en utilizar las transacciones manuales de tal forma que cuando ocurra un error se lleve a cabo un rollback para deshacer las inserciones, me podrías dar algún consejo, veras este es mi código:

    @transaction.atomic
    def calculo_honorario(self,periodo):
        honorarios = Periodo_calculo.objects.filter(tabla='Honorario',periodo_dependencia__cat_periodo = periodo).values_list('object_id',flat=True)
        if honorarios:
            bandera = True
            plaza_honorario = Honorario.objects.filter(pk__in=honorarios)
            for honorario in plaza_honorario:
                insertar = True
                id_registro = 0
                try:
                    encuentra_honorario = periodo_temp.objects.get(empleado=honorario.empleado,objecto_id=honorario.id,tabla="HONORARIOS")
                    if encuentra_honorario:
                        insertar = False
                        id_registro = encuentra_honorario.id
                except:
                    pass
                ##### datos que se guardaran en la tabla temporal #####
                monto =Decimal(honorario.sueldo)
                unidad_id=honorario.pud_u_administrativa_id
                quincena_id = int(periodo)
                proyecto_id = honorario.cat_proyecto.id
                empleado_id = honorario.empleado.id
                usuario_id_h = self.request.user.id
                tipo_nomina = 2
                pagador = honorario.cat_pagador.pk
                objecto_id = int(honorario.id)
                tabla = "HONORARIOS"

                ###Llama función calcular_honorarios ###
                try:
                    c = connection.cursor()
                    try:
                        c.execute("BEGIN")
                        c.callproc("calculo_honorario", [monto,unidad_id,quincena_id,proyecto_id,empleado_id,usuario_id_h,tipo_nomina,pagador,objecto_id,tabla,insertar,id_registro])
                        results = c.fetchone()
                        c.execute("COMMIT")
                    except Exception as err:
                        error = err
                        print(error)
                        bandera = "Error"
                        transaction.rollback()
                    finally:
                        c.close()
                except:
                        bandera = 'Error'
                        return bandera
        else:
            bandera=False
            return bandera
        return bandera

Edgar De La Cruz

unread,
Nov 10, 2015, 12:29:21 PM11/10/15
to Django-es
Hola Cornelio, soy de México, el proyecto no es mio como tal, pero te dejo mi email ( zeromorph20 ---gmail )  para conversar e intercambiar ideas. Saludos.
Reply all
Reply to author
Forward
0 new messages