Novas tabelas devem ser criadas em hook_update_N ()?


11

Quando você cria uma nova tabela hook_schema(), essa tabela deve ser adicionada hook_update_N()também? Ou há algum truque, ou algo que eu perdi, para que as atualizações de dados adicionem tabelas automaticamente?

A documentação de hook_update_N () não explica nada sobre a introdução de novas tabelas, enquanto a documentaçãohook_schema() diz:

As tabelas declaradas por esse gancho serão criadas automaticamente quando o módulo for ativado pela primeira vez e removidas quando o módulo for desinstalado.

(Destaque é meu)

E se sim, como evitar a duplicação das definições de esquema para a nova tabela em hook_update_N () e hook_schema (). Simplesmente consultando o esquema da seguinte maneira:

 function hook_update_N(&$sandbox) {
   $schema = hook_schema();
   $name = "foo";
   $table = $schema["foo"];
   db_create_table($name, $table);
 }

Parece funcionar, mas, ao mudar a tabela novamente, falhará se um usuário executar as atualizações e executar dois ou mais hook_update_N () s. Afinal: o primeiro hook_update_N já instalará o banco de dados correto e o segundo hook_update_M () tentará adicionar / alterar / alterar colunas que já estavam atualizadas.

Como você lida com isso?


Consulte drupal.org/node/150215 para obter documentação. Então, basicamente, adicionar uma nova tabela após a instalação de um módulo é via hook_update_N, mas você também adiciona a definição da tabela ao hook_schema para novos usuários ou novas instalações. Portanto, resumir se você fizer alterações na tabela para atualizar as tabelas atuais via hook_update_N, mas também mesclar as alterações no hook_schema.
— junedkazi

1
Portanto, não há como evitar violar o DRY, ao que parece. Pena.
— Berkes

nada do que eu saiba. Mas você pode escrever uma função pequena que tenha a definição de esquema e chamar essa definição nas duas funções.
— junedkazi

@berkes Pode-se definir outra função que retorne o esquema adicional e faça referência a ele nos ganchos de atualização e instalação.
— User1359

Respostas:


15

Então, basta copiar e colar a partir de drupal.org. Você também precisa adicionar a definição de esquema ao hook_schema.

/**
 * Create new database table {mytable2}.
 */
function mymodule_update_7101() {
  $schema['mytable2'] = array(
     // table definition array goes here
  );
  db_create_table('mytable2', $schema['mytable2']);
}

Você quer dizer que não há outra maneira de copiar a definição de tabela de hook_schema () para hook_update_N (). Em outras palavras: que não há como evitar violar o DRY?
— Berkes

3
@berkes local ... há uma boa explicação de por que é aqui , caso você ainda não tenha visto isso
— Clive

@ Clive Esse é um exemplo incrível. Nunca vi isso antes. 1
— junedkazi 4/10/12

@junedkazi Há um link para ele no link que você forneceu no seu comentário;)
— Clive

-2

mymodule_update_7101 () é bom, junto com este gancho, se adicionarmos um hook_install () para executar o mesmo enquanto a instalação do módulo, em vez da definição hook_schema (), também funciona para mim.


/**
 * Implements hook_install().
 */
function mymodule_install() {
  // Change the update number accordingly for more updates.
  for ($i = 7101; $i < 7102; $i++) {
    $update_func = 'mymodule_update_' . $i;
    if (function_exists($update_func)) {
      $update_func();
    }
  }
}


É uma prática muito melhor do Drupal usar a API conforme indicado. Use hook_schema () e hook_update_N () diretamente. Uma coisa que faço é chamar a implementação hook_schema do meu módulo em hook_update_N () e, em seguida, execute as respectivas funções db_ *.
— Mrclclfefe

hook_install()não deve chamar nenhuma implementação hook_update_N (), simplesmente: hook_install()é para instalar um módulo pela primeira vez, o que significa que não há tabelas para atualizar. Além disso, seu código não funcionaria para atualizações que precisam de um lote para serem executadas.
— kiamlaluno

Esse trecho de código será útil se você estiver atualizando o esquema e apenas para fins de implantação. Para um sistema ativo existente, isso não pode ser usado.
— Akhila V Nair
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.