¿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?


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']);
}

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


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.