[pyar] Campo Primario Web2py
Mariano Mara
mariano.mara en gmail.com
Vie Feb 4 17:38:12 ART 2011
On 04.02.11 15:25, Roberto Perdomo wrote:
> a mi me quedó asi definitivamente y funciona al 100% con Postgres:
>
> db.tipo_nomina.nomina.requires= [IS_NOT_EMPTY(error_message='Ha
> introducido un valor vacío'),
> IS_NOT_IN_DB(db, 'tipo_nomina.nomina',
> error_message = 'Este
> registro ya se encuentra procesado'),
> IS_LENGTH(maxsize=40, minsize=5,
> error_message='Introduzca entre %(min)g y %(max)g caracteres')
> ]
¿Pero estás reforzando la regla a nivel de base de datos con un
constraint unique o primary key?
Hace mucho que no toco web2py así que mi consejo es "framework
agnostic" (capaz que ya lo tuviste en cuenta a todo esto pero
permitime dejar constancia por si le sirve a alguien más):
las reglas que se puedan reforzar a nivel de base de datos
(clave primaria y foranea, nulidad, algunas validaciones que te permita
el motor en una instrucción "check constraint", etc) *tienen* que estar
en la base.
Desconozco el alcance de tu proyecto o cuanto esfuerzo le querés poner
pero sea cual sea vos no podés asegurar que tu frontend va a ser la
única vía por la cual alguien va a acceder a los datos para siempre.
Algunos ejemplos simples:
* mañana hay que hacer una inserción masiva de registros (pongamos que
con un csv)
* mañana se te da por agregar una API (tan social hoy en día) para que
otras aplicaciones se puedan conectar y modificar tus datos vía
servicios web
* mañana vos te vas, viene otro al que no le gusta web2py y convence a
tu jefe que <nuevo lenguaje en boga> es lo mejor y reescribe toda la
aplicación en ese nuevo lenguaje.
Cualquiera de esos escenarios van a pasar tus restricciones a nivel
controlador/vista como arroyo al tranco y vas a terminar con una base
llena de duplicados, registros huerfanos y nulos donde no debería ser
posible.
Entiendo que a veces ponerse a trabajar en esas cosas en la base es una
molestia:
* porque tenes un chequeo en el controlador y otra vez en la base
(aunque no es necesario que así sea)
* porque es más rápido insertar en una tabla sin restricciones que en
una donde tenés algún control (una unique o primary hace un full scan
del índice)
* porque no todos los motores de bases de datos soportan las mismas
reglas y entonces a veces tu aplicación no es tan "database
independent" como te gustaría.
pero teniendo las reglas a nivel de base, dormís tranquilo sabiendo que
muchos escenarios donde pueden haber problemas no te van a suceder. De
última es más fácil aclarar/arreglar un "duplicate index on table" que
ponerse a borrar registros en cascadas dentro de la base. Como valor
agregado, la base de datos entiende mejor tu modelo y sabe cual es la
mejor forma de ejecutar un query que le pidas.
Como dicen a veces "las aplicaciones pasan pero los datos quedan".
>
> El 04/02/11, Mariano Reingart <reingart en gmail.com> escribió:
> > Cuando son varios validadores, van en una lista:
> >
> > db.nadadores.fecnac.requires = [ IS_DATE(error_message='Formato
> > erroneo? (AAA-MM-DD)'),
> >
> > IS_NOT_EMPTY(error_message='Campo Obligatorio'), ]
> >
> > Sds
> >
> >
> > 2011/2/4 nicolás rosbaco <antiyanki en gmail.com>:
> >> Hola, lo probé y me pasa esto:
> >>
> >> 2011/2/3 Roberto Perdomo <robertop23 en gmail.com>
> >>>
> >>> 2011/2/3 nicolás rosbaco <antiyanki en gmail.com>
> >>>>
> >>>> OK. entonces: unique, evita la inserción de tuplas en las tablas (si la
> >>>> clave esta repetida)... y pasa por cuenta del programador evitar que
> >>>> ello
> >>>> ocurra (o atrapar la excepción supongo yo)
> >>>>
> >>>> con IS_NOT_IN_DB las verificaciones se hacen antes de modificar la
> >>>> tabla... pero la tabla no es creada con la restricción referida ¿está
> >>>> bien?
> >>>>
> >>>> Por otro lado: como hago (cuando creo la tabla) si quiero incluir más de
> >>>> un requires???
> >>>
> >>> Si necesitas mas de uno lo haces asi:
> >>>
> >>> db.define_table('tipo_nomina'
> >>> ,
> >>> SQLField('nomina', type='string', length=40, notnull=False,
> >>> unique=True, required=True))
> >>>
> >>>
> >>>
> >>> db.tipo_nomina.nomina.requires= IS_IN_DB(db, db.tipo_nomina.nomina,
> >>> error_message='Ha introducido un valor vacío o registrado')
> >>>
> >>>
> >>> db.tipo_nomina.nomina.requires = IS_LENGTH(maxsize=40, minsize=5,
> >>> error_message='Introduzca entre %(min)g y %(max)g caracteres')
> >>>
> >>
> >> Yo tengo las siguientes condiciones:
> >> db.nadadores.fecnac.requires = IS_DATE(error_message='Formato erroneo?
> >> (AAA-MM-DD)')
> >> db.nadadores.fecnac.requires = IS_NOT_EMPTY(error_message='Campo
> >> Obligatorio')
> >>
> >> si ingreso en el campo fecha cualquier verdura la tupla se agrega (después
> >> claro da error al intentar listar la tabla) a la tabla!
> >>
> >> Si dejo vacío el campo chilla el validador! por lo tanto: el último
> >> requires
> >> esta siendo considerado....
> >>
> >> Ahora (acá lo curioso) si borro el último requires y luego ingreso
> >> cualquier
> >> verdura en el campo fecha chilla!...
> >>
> >> Me da a pensar que un requires anula el anterior.... ¿puede ser?
> >>
> >>>
> >>> db.tipo_nomina.nomina.requires =
> >>> IS_MATCH('^[a-zA-ZáéíóúÁÉÍÓÚ\s]+$',error_message='Introduzca solo
> >>> letras')
> >>>>
> >>>> Bueno gente, esto esta re bueno. Muchas gracias
> >>>>
> >>>>
> >>>> El 3 de febrero de 2011 19:49, Mariano Reingart <reingart en gmail.com>
> >>>> escribió:
> >>>>>
> >>>>> Las restricciones primarykey, unique y notnull se aplican a nivel de
> >>>>> datos, web2py no las verifica, simplemente crea las tablas con esas
> >>>>> condiciones, y el servidor de base de datos debería hacer el resto
> >>>>> (por lo que los conectores lanzan excepciones).
> >>>>>
> >>>>> Los validadores (IS_NOT_IN_DB, IS_IN_DB, IS_NOT_EMPTY) funcionan a
> >>>>> nivel de los controladores/vistas, son verificados antes de modificar
> >>>>> la base de datos, cuando el usuario utiliza un formulario (y muestran
> >>>>> un mensaje de error en la pantalla, con la posibilidad de corregir el
> >>>>> formulario).
> >>>>>
> >>>>> En el libro está explicado en detalle:
> >>>>>
> >>>>>
> >>>>> http://www.latinuxpress.com/books/drafts/web2py/caps/cap6.html#representacion-de-registros
> >>>>>
> >>>>> En este caso, con IS_NOT_IN_DB no aceptaría el formulario mostrando un
> >>>>> error al usuario si esta duplicado algún valor.
> >>>>>
> >>>>> Sds
> >>>>>
> >>>>> 2011/2/3 nicolás rosbaco <antiyanki en gmail.com>:
> >>>>> > me faltó decir que estoy trabajando con web2py
> >>>>> >
> >>>>> > El 3 de febrero de 2011 19:30, nicolás rosbaco <antiyanki en gmail.com>
> >>>>> > escribió:
> >>>>> >>
> >>>>> >> Hola, mira no tengo la solución... pero si me paso algo parecido y
> >>>>> >> de
> >>>>> >> pronto por acá puedo llegar a saber que pasa.
> >>>>> >>
> >>>>> >> En mi caso el unique tampoco anduvo (¿ignoro por que??) pero utilicé
> >>>>> >> lo
> >>>>> >> siguiente:
> >>>>> >>
> >>>>> >> db.nadadores.email.requires = IS_NOT_IN_DB(db, 'nadadores.email',
> >>>>> >> error_message='Dirección de mail duplicada. Ya existe un usuario
> >>>>> >> registrado
> >>>>> >> con esta dirección de mail')
> >>>>> >>
> >>>>> >> La verdad que me gustaría saber para que sirve el unique, ya que
> >>>>> >> suponía
> >>>>> >> lo mismo que vos
> >>>>> >>
> >>>>> >>
> >>>>> >> 2011/2/3 Roberto Perdomo <robertop23 en gmail.com>
> >>>>> >>>
> >>>>> >>> Buenas tardes,
> >>>>> >>>
> >>>>> >>> Alguien de casualidad tiene conocimiento en cuanto a como definir
> >>>>> >>> un
> >>>>> >>> campo primario adicional en una tabla.
> >>>>> >>>
> >>>>> >>> Tengo por ejemplo una tabla:
> >>>>> >>>
> >>>>> >>> db.define_table('tipo_nomina',
> >>>>> >>> SQLField('nomina', type='string', length=40, notnull=True,
> >>>>> >>> required=True, unique=True)
> >>>>> >>> )
> >>>>> >>>
> >>>>> >>> Donde unique=True supuestamente debería funcionar y hacer que no se
> >>>>> >>> permitan valores repetidos para el campo nomina, pero, al añadir un
> >>>>> >>> valor
> >>>>> >>> repetido resulta el siguiente error:
> >>>>> >>>
> >>>>> >>>
> >>>>> >>> IntegrityError: duplicate key value violates unique constraint
> >>>>> >>> "tipo_nomina_nomina_key"
> >>>>> >>>
> >>>>> >>> Investigue un poco y dicen que es un error de la Base de Datos, en
> >>>>> >>> mi
> >>>>> >>> caso es Postgres. Entonces Web2py no es capaz de manejar o mejor
> >>>>> >>> dicho,
> >>>>> >>> generar un error para cuando se esta insertando un valor repetido
> >>>>> >>> en
> >>>>> >>> un
> >>>>> >>> campo?
> >>>>> >>>
> >>>>> >>> Intente con primarykey = ['nomina'], pero fue infructuoso.
> >>>>> >>>
> >>>>> >>> lo que quisiera seria realmente poder definir un campo primario
> >>>>> >>> para
> >>>>> >>> evitar valores repetidos, pero no encuentro la manera adecuada para
> >>>>> >>> ello.
> >>>>> >>>
> >>>>> >>> PD: los formularios son generado utilizando SQLFORM y CRUD
> >>>>> >>>
> >>>>> >>> Gracias de antemano
> >>>>> >>>
> >>>>> >>>
> >>>>> >>>
> >>>>> >>>
> >>>>> >>> _______________________________________________
> >>>>
> >>>> --
> >>>> "En un país colonial las oligarquías son las dueñas de los diccionarios"
> >>>> (John William Cooke)
> >>>>
More information about the pyar
mailing list