Le nuove tabelle devono essere create in hook_update_N ()?


11

Quando si crea una nuova tabella in hook_schema(), anche quella tabella deve essere aggiunta in un hook_update_N()? Oppure c'è qualche trucco, o qualcosa che mi è sfuggito, per fare in modo che gli aggiornamenti dei databae aggiungano automaticamente le tabelle?

La documentazione di hook_update_N () non spiega nulla sull'introduzione di nuove tabelle, mentre la documentazione dihook_schema() dice:

Le tabelle dichiarate da questo hook verranno create automaticamente quando il modulo viene abilitato per la prima volta e rimosse quando il modulo viene disinstallato.

(Il momento saliente è mio)

E in tal caso, come evitare al meglio la duplicazione delle definizioni dello schema per la nuova tabella in hook_update_N () e hook_schema (). Facendo semplicemente riferimento allo schema come segue:

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

Sembra funzionare, ma cambiando di nuovo la tabella, fallirà se un utente esegue gli aggiornamenti e riesce a eseguire due o più hook_update_N (). Dopotutto: il primo hook_update_N installerà quindi già il database corretto e il secondo hook_update_M () proverà ad aggiungere / cambiare / modificare colonne che erano già aggiornate.

come lo gestisci?


Fare riferimento a drupal.org/node/150215 per la documentazione. Quindi, in sostanza, aggiungere una nuova tabella dopo l'installazione di un modulo avviene tramite hook_update_N ma si aggiunge anche la definizione della tabella a hook_schema per i nuovi utenti o nuove installazioni. Quindi riassumilo se apporti delle modifiche alla tabella per aggiornare le tabelle correnti tramite hook_update_N ma unisci anche le modifiche in hook_schema.
Junedkazi,

1
Quindi non c'è modo di evitare di violare il DRY, a quanto pare. Pietà.
Berkes,

nulla di cui sono a conoscenza. Ma puoi scrivere una piccola funzione che ha la definizione dello schema e chiamarla in entrambe le funzioni.
Junedkazi,

@berkes Uno potrebbe definire un'altra funzione che restituisce lo schema aggiuntivo e fare riferimento ad esso sia negli hook di aggiornamento che di installazione.
user1359

Risposte:


15

Quindi solo una copia incolla da drupal.org. È inoltre necessario aggiungere la definizione dello schema 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']);
}

Vuoi dire che non c'è altro modo che copiare la definizione della tabella da hook_schema () in hook_update_N (). In altre parole: che non c'è modo di evitare di violare il DRY?
Berkes,

3
@berkes spot on ... c'è una buona spiegazione per questo che è qui nel caso in cui non si è già visto
Clive

@Clive Questo è un esempio fantastico. Non l'ho mai visto prima. +1
Junedkazi,

@junedkazi C'è un link ad esso sul link che hai fornito nel tuo commento;)
Clive

-2

mymodule_update_7101 () è buono, insieme a questo hook se aggiungiamo un hook_install () per eseguire lo stesso mentre l'installazione del modulo invece della definizione hook_schema () funziona anche per me.


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


È molto meglio che Drupal utilizzi l'API come indicato. Utilizzare hook_schema () e hook_update_N () direttamente. Una cosa che faccio è chiamare l'implementazione hook_schema del mio modulo in hook_update_N () e quindi eseguire le rispettive funzioni db_ *.
mradcliffe,

hook_install()non dovrebbe chiamare nessuna implementazione hook_update_N (), per un semplice fatto: hook_install()è per installare un modulo per la prima volta, il che significa che non ci sono tabelle da aggiornare. Inoltre, il codice non funzionerebbe per gli aggiornamenti che richiedono l'esecuzione di un batch.
kiamlaluno

Questo frammento di codice sarà utile se stai aggiornando lo schema e solo a scopo di distribuzione. Per un sistema live esistente, questo non può essere utilizzato.
Akhila V Nair,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.