¿Deben crearse nuevas tablas en hook_update_N ()?

11

Cuando crea una nueva tabla hook_schema(), ¿debería agregarse esa tabla también en una hook_update_N()? ¿O hay algún truco, o algo que me perdí, para que las actualizaciones de databae agreguen tablas automáticamente?

La documentación de hook_update_N () no explica nada acerca de la introducción de nuevas tablas, mientras que la documentación dehook_schema() dice:

Las tablas declaradas por este enlace se crearán automáticamente cuando el módulo se habilite por primera vez y se eliminarán cuando se desinstale el módulo.

(Lo más destacado es mío)

Y si es así, cómo evitar mejor duplicar las definiciones de esquema para la nueva tabla tanto en hook_update_N () como en hook_schema (). Simplemente refiriéndose al esquema de la siguiente manera:

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

Parece funcionar, pero al cambiar la tabla nuevamente, fallará si un usuario ejecuta las actualizaciones y puede ejecutar dos o más hook_update_N () s. Después de todo: el primer hook_update_N ya instalará la base de datos correcta y el segundo hook_update_M () intentará agregar / cambiar / alterar las columnas que ya estaban actualizadas.

Como tratas con esto?

Berkes
fuente
Consulte drupal.org/node/150215 para obtener documentación. Básicamente, agregar una nueva tabla después de instalar un módulo es a través de hook_update_N, pero también agrega la definición de la tabla al hook_schema para nuevos usuarios o nuevas instalaciones. Así que resuma si realiza cambios en la tabla para actualizar las tablas actuales a través de hook_update_N pero también combina los cambios en hook_schema.
junedkazi
1
Parece que no hay forma de evitar violar DRY. Lástima.
Berkes
nada que yo sepa. Pero puede escribir una pequeña función que tenga la definición de esquema y llamar a esa definición en ambas funciones.
junedkazi
@berkes One podría definir otra función que devuelva el esquema adicional y hacer referencia a él en los enlaces de actualización e instalación.
user1359

Respuestas:

15

Tan solo una copia pegada de drupal.org. También debe agregar la definición de esquema a 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']);
}
junedkazi
fuente
¿Quiere decir que no hay otra forma de copiar la definición de tabla de hook_schema () en hook_update_N (). En otras palabras: ¿que no hay forma de evitar violar DRY?
Berkes
3
@berkes detecta ... hay una muy buena explicación de por qué eso está aquí en caso de que aún no lo haya visto
Clive
@Clive Ese es un excelente ejemplo. Nunca lo vi antes. +1
junedkazi
@junedkazi Hay un enlace en el enlace que proporcionó en su comentario;)
Clive
-2

mymodule_update_7101 () es bueno, junto con este gancho si agregamos un hook_install () para ejecutar lo mismo mientras que la instalación del módulo en lugar de la definición hook_schema () también funciona para mí.


/**
 * 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();
    }
  }
}

Akhila V Nair
fuente
Es mucho mejor la práctica de Drupal usar la API como se indica. Use hook_schema () y hook_update_N () directamente. Una cosa que hago es llamar a la implementación hook_schema de mi módulo en hook_update_N (), y luego ejecutar las funciones db_ * respectivas.
mradcliffe
hook_install()no debería llamar a ninguna implementación de hook_update_N (), por un simple hecho: hook_install()es para instalar un módulo por primera vez, lo que significa que no hay tablas para actualizar. Además, su código no funcionaría para las actualizaciones que necesitan un lote para ejecutarse.
kiamlaluno
Este fragmento de código será útil si está actualizando el esquema y solo con fines de implementación. Para un sistema en vivo existente, esto no se puede usar.
Akhila V Nair