Hook_update_N () içinde yeni tablolar oluşturulmalı mı?


11

İçinde yeni bir tablo oluşturduğunuzda hook_schema(), o tablo da eklenmelidir hook_update_N()mi? Ya da databae güncellemelerinin otomatik olarak tablo eklemesi için bir hile ya da kaçırdığım bir şey var mı?

Hook_update_N () dokümantasyonu oysa yeni tablolar tanıtan hakkında hiçbir şey açıklamıyor belgelenmesihook_schema() diyor ki:

Bu kanca tarafından bildirilen tablolar modül ilk etkinleştirildiğinde otomatik olarak oluşturulur ve modül kaldırıldığında kaldırılır.

(Vurgulama benimdir)

Ve öyleyse, hem hook_update_N () hem de hook_schema () 'da yeni tablo için şema tanımlarının çoğaltılmasından en iyi nasıl kaçınılır. Şemaya aşağıdaki gibi atıfta bulunmanız yeterlidir:

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

Çalışıyor gibi görünüyor, ancak bir kullanıcı güncelleştirmeleri çalıştırır ve iki veya daha fazla hook_update_N () s çalıştırırsa tabloyu yeniden değiştirdiğinizde başarısız olur. Sonuçta: ilk hook_update_N zaten doğru veritabanını kuracak ve ikinci hook_update_M () zaten güncel olan sütunları eklemeye / değiştirmeye / değiştirmeye çalışacaktır.

Nasıl anlaştın onunla birlikte?


Doküman için drupal.org/node/150215 adresine bakın . Temel olarak bir modül kurulduktan sonra yeni bir tablo eklemek hook_update_N üzerinden yapılır, ancak tablo tanımını yeni kullanıcılar veya yeni kurulumlar için hook_schema'ya da ekleyebilirsiniz. Geçerli tabloları hook_update_N üzerinden güncellemek için herhangi bir tablo değişikliği yaparsanız, ancak hook_schema'daki değişiklikleri birleştirirseniz özetleyin.
— junedkazi

1
Yani DRY'yi ihlal etmekten kaçınmanın bir yolu yok gibi görünüyor. Yazık.
— Berkes

farkında olduğum hiçbir şey. Ancak şema tanımına sahip küçük bir işlev yazabilir ve bu tanımı her iki işlevde de çağırabilirsiniz.
— junedkazi

@berkes Ek şemayı döndüren başka bir işlev tanımlanabilir ve hem güncelleme hem de yükleme kancalarında bu işleve başvurabilir.
— user1359

Yanıtlar:


15

Drupal.org'dan bir kopya yapıştır. Ayrıca hook_schema'ya şema tanımı eklemeniz gerekir.

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

Tablo tanımını hook_schema () 'dan hook_update_N ()' a kopyalamanın başka bir yolu olmadığını mı söylüyorsunuz? Başka bir deyişle: DRY'yi ihlal etmekten kaçınmanın bir yolu olmadığını?
— Berkes

3
@berkes spot on ... daha önce görmediyseniz , neden burada olduğunu çok iyi bir açıklama var
— Clive

@Clive Bu harika bir örnek. Daha önce hiç görmedim. +1
— junedkazi

@junedkazi Yorumunuzda belirttiğiniz bağlantıda bir bağlantı var;)
— Clive

-2

mymodule_update_7101 () iyi, bu kanca ile birlikte aynı kanca yürütmek için bir hook_install () eklersek, hook_schema () tanımı yerine modül kurulumu da benim için çalışıyor.


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


API'yı belirtildiği şekilde kullanmak çok daha iyi Drupal uygulamasıdır. Doğrudan hook_schema () ve hook_update_N () kullanın. Yaptığım bir şey, modülümün hook_update_N () içinde hook_schema uygulamasını çağırmak ve sonra ilgili db_ * işlevlerini çalıştırmaktır.
— mradcliffe

hook_install()Basitçe söylemek gerekirse, herhangi bir hook_update_N () uygulamasını çağırmamalısınız: hook_install()bir modülü ilk kez kurmak içindir, yani güncellenecek tablolar yoktur. Ayrıca, çalıştırmanız için toplu iş gerektiren güncelleştirmeler için kodunuz çalışmaz.
— kiamlaluno

Bu kod snippet'i, şemayı güncelleştiriyorsanız ve yalnızca dağıtım amacıyla kullanıldığında yararlı olacaktır. Mevcut bir canlı sistem için bu kullanılamaz.
— Akhila V Nair
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.