sábado, 24 de septiembre de 2011

Campos únicos de tipo entero en Doctrine 1.2

He comprobado personalmente en un par de proyectos que curiosamente Doctrine no genera las restricciones UNIQUE sobre campos de tipo entero (int) en la base de datos, aunque sí lo hace con campos tipo texto. Por ejemplo, si tenemos una clase definida así:

Mascota:

  connection: doctrine
  tableName: mascota
  actAs: [Timestampable]
  columns:
    id:
      type: integer(4)
      primary: true
      autoincrement: true
    dueno_id:
      type: integer(4)
      unique: true
    descripcion:
      type: string()
      notnull: true


Symfony ejecutará este SQL en el gestor de bases de datos:

CREATE TABLE mascota (id SERIAL, dueno_id INT, descripcion TEXT NOT NULL, created_at TIMESTAMP NOT NULL, updated_at TIMESTAMP NOT NULL, PRIMARY KEY(id));

Con lo que no tendremos la validación en la base de datos (podemos comprobarlo al ver la descripción de la tabla en el gestor), aunque por lo menos sí lo hace en la aplicación, ya que si miramos el formulario base veremos el postvalidator con la restricción unique sobre el campo 'dueno_id':

...
$this->validatorSchema->setPostValidator(
new sfValidatorDoctrineUnique(array('model' => 'AbFacturacionDesvinculacion', 'column' => array('suscripcion_id')))
);
...

Si cambiamos el tipo del campo 'dueno_id' a string(255) por ejemplo, symfony ejecutará este sql:

CREATE TABLE mascota (id SERIAL, dueno_id VARCHAR(255) UNIQUE, descripcion TEXT NOT NULL, created_at TIMESTAMP NOT NULL, updated_at TIMESTAMP NOT NULL, PRIMARY KEY(id));

Pero evidentemente eso no es lo que queremos y como soy paranoico yo quiero mi campo tipo entero con restricción unique definido en la base de datos. Para lograrlo tendremos que definirlo como un índice único de la clase:

Mascota:
  connection: doctrine
  tableName: mascota
  actAs: [Timestampable]
  columns:
    id:
      type: integer(4)
      primary: true
      autoincrement: true    dueno_id:
      type: integer(4)    descripcion:      type: string()      notnull: true
   indexes:
    mascota_dueno_index:
      fields: [dueno_id]
      type: unique

De este modo la tabla creada en la base de datos corresponderá a este sql:

CREATE TABLE mascota (id SERIAL, dueno_id INT UNIQUE, descripcion TEXT NOT NULL, created_at TIMESTAMP NOT NULL, updated_at TIMESTAMP NOT NULL, PRIMARY KEY(id));

Curioso, aunque un poco molesto la verdad ya que es un comportamiento algo errático poco deseable.