Caution: You are browsing the legacy symfony 1.x part of this website.

Como escrever um schema do Propel com a sintaxe alternativa

1.2
Symfony version
1.1
Language

Visão Geral

Com o symfony 1.1, você pode escolher descrever a sua estrutura do modelo relacional em uma nova sintaxe YAML. O symfony reconhece os arquivos schema.yml escritos tanto com a sintaxe descrita no Capítulo 8 do livro do symfony, como os escritos com a sintaxe descrita abaixo. A sintaxe alternativa é mais orientada à objeto e torna o processo da fusão de vários esquemas mais fácil de entender.

Exemplo Base

Considere o seguinte schema, usando a sintaxe atual:

propel:
  _attributes:      { noXsd: false, defaultIdMethod: none, package: lib.model }
  ab_group:
    _attributes:    { phpName: Group, package: foo.bar.lib.model }
    id:
    name:           varchar(50)

  cd_user:
    _attributes:    { phpName: User, isI18N: true, i18nTable: cd_user_i18n }
    first_name:     { type: varchar, size: 255, default: "Anonymous" }
    last_name:      varchar(50)
    age:            { type: integer, required: true, index: true }
    ab_group_id:
    created_at:

  cd_user_i18n:
    description:    longvarchar

  ef_article:
    title:          { type: longvarchar, required: true, index: unique }
    stripped_title: { type: longvarchar, required: true, primaryKey: true, sequence: my_custom_sequence_name }
    user_id:
    my_group:       { type: integer, foreignTable: ab_group, foreignReference: id, onDelete: setnull }
    created_at:     timestamp
    updated_at:

  ij_article:
    _attributes:    { phpName: Article }
    title:          varchar(50)
    user_id:        { type: integer }
    _foreignKeys:
      -
        foreignTable: cd_user
        onDelete:     cascade
        references:
          - { local: user_id, foreign: id }
    created_at:
    _indexes:
      my_index:       [title, user_id]
    _uniques:
      my_other_index: [created_at]
    _behaviors:
      paranoid:     { column: deleted_at }

  ab_group_i18n:
    motto:            longvarchar

Sintaxe alternativa

Exemplo base, com a sintaxe alternativa

Aqui está como escrever exatamente a mesma estrutura como a listada acima, com a sintaxe alternativa:

connection:           propel
noXsd:                false
defaultIdMethod:      none
package:              lib.model

classes:
  Group:
    tableName:        ab_group
    package:          foo.bar.lib.model
    columns:
      id:
      name:           varchar(50)

  User:
    tableName:        cd_user
    isI18N:           true
    i18nTable:        cd_user_i18n
    columns:
      first_name:     { type: varchar, size: 255, default: "Anonymous" }
      last_name:      varchar(50)
      age:            { type: integer, required: true, index: true }
      ab_group_id:
      created_at:

  CdUserI18n:
    columns:
      description:    longvarchar

  EfArticle:
    columns:
      title:          { type: longvarchar, required: true, index: unique }
      stripped_title: { type: longvarchar, required: true, primaryKey: true, sequence: my_custom_sequence_name }
      user_id:
      my_group:       { type: integer, foreignClass: Group, foreignReference: id, onDelete: setnull }
      created_at:     timestamp
      updated_at:

  Article:
    tableName:        ij_article
    columns:
      title:          varchar(50)
      user_id:        { type: integer }
      created_at:
    foreignKeys:
      -
        foreignTable: cd_user
        onDelete:     cascade
        references:
          - { local: user_id, foreign: id }
    indexes:
      my_index:       [title, user_id]
    uniques:
      my_other_index: [created_at]
    behaviors:
      paranoid:     { column: deleted_at }

  AbGroupI18n:
    columns:
      motto:          longvarchar

A principal diferença é que você declara classes, não tabelas, usando a tabela phpName como a chave.

Esta sintaxe alternativa também é mais explícita, uma vez que você deve criar entradas para classes e colunas. Mas torna-se livre do hack feio _attributes da sintaxe atual, desta forma, o schema.yml não tenta imitar uma sintaxe XML.

Por último mas não menos importante, todas as "mágicas" da sintaxe clássica continuam lá (auto definição das chaves primárias, chaves estrangeiras, tabelas i18n, etc.)

Configurações de conexão

Ao invés de serem definidas como _attributes da conexão, as configurações da conexão, juntamente com o nome da conexão, são todas chaves no nível-1:

connection:           propel
noXsd:                false
defaultIdMethod:      none
package:              lib.model

Todas estas chaves são opcionais, incluindo a chave connection. Se ela não for informada, o symfony utilizará como valor default o propel.

Classes

Uma definição de classe lista o nome da tabela no banco de dados, as colunas, chaves estrangeiras, índices e behaviours em uma sintaxe natural chave/valores:

Article:
  tableName:        ij_article
  columns:
    title:          varchar(50)
    user_id:        { type: integer }
    created_at:
  foreignKeys:
    -
      foreignTable: cd_user
      onDelete:     cascade
      references:
        - { local: user_id, foreign: id }
  indexes:
    my_index:       [title, user_id]
  uniques:
    my_other_index: [created_at]
  behaviors:
    paranoid:     { column: deleted_at }

Note que você pode definir chaves estrangeiras tanto com o atributo usual foreignTable, que espera o nome da tabela, ou através do novo atributo foreignClass, que espera o nome da classe.

Schemas mistos

Você pode ter, em um projeto, schemas mistos com a sintaxe atual e a sintaxe alternativa.

O sistema de extensão de schema, descrito no Capítulo 17 do livro do symfony, funciona seja qual for a sintaxe do schema original e qualquer que seja a sintaxe personalizada do schema. Isto significa que você pode personalizar um schema já existente com a sintaxe clássica usando um esquema personalizado com a sintaxe alternativa, e vice-versa. O symfony irá fazer a conversão internamente tornando a fusão sempre possível.

Note que a fusão de schema é fácil de entender quando considerada a sintaxe alternativa para ambos os schemas original e personalizado. De fato, este é um formato interno utilizado pelo symfony para a fusão. A listagem seguinte mostra a fusão dos schemas:

# Schema original, em plugins/myPlugin/config/schema.yml
classes:
  User:
    tableName:        cd_user
    columns:
      first_name:     { type: varchar, size: 255, default: "Anonymous" }
      last_name:      varchar(50)
      age:            { type: integer, required: true, index: true }
      created_at:

  Article:
    tableName:        ij_article
    columns:
      title:          varchar(50)
      user_id:        { type: integer }
      created_at:
    foreignKeys:
      -
        foreignTable: cd_user
        onDelete:     cascade
        references:
          - { local: user_id, foreign: id }

# Schema personalizado, em myPlugin_schema.custom.yml
connection: myConnection
classes:
  Group:
    tableName:        ab_group
    package:          foo.bar.lib.model
    behaviors:        [paranoid]
    columns:
      id:
      name:           varchar(50)

  User:
    tableName:        ef_user
    isI18N:           true
    i18nTable:        cd_user_i18n
    columns:
      ab_group_id:

  Article:
    columns:
      updated_at:

# Schema resultante, realizada a fusão interna e utilizado para o modelo e a geração de sql
connection: myConnection
classes:
  Group:
    tableName:        ab_group
    package:          foo.bar.lib.model
    behaviors:        [paranoid]
    columns:
      id:
      name:           varchar(50)

  User:
    tableName:        cd_user
    isI18N:           true
    i18nTable:        cd_user_i18n
    columns:
      first_name:     { type: varchar, size: 255, default: "Anonymous" }
      last_name:      varchar(50)
      age:            { type: integer, required: true, index: true }
      ab_group_id:
      created_at:

  Article:
    tableName:        ij_article
    columns:
      title:          varchar(50)
      user_id:        { type: integer }
      created_at:
      updated_at:
    foreignKeys:
      -
        foreignTable: cd_user
        onDelete:     cascade
        references:
          - { local: user_id, foreign: id }

Para maior clareza, recomenda-se o uso da sintaxe alternativa para os schemas, tanto quanto possível.