ต้องสร้างตารางใหม่ใน hook_update_N () หรือไม่


11

เมื่อคุณสร้างตารางใหม่hook_schema()ควรเพิ่มตารางนั้นhook_update_N()ด้วยหรือไม่ หรือมีเคล็ดลับหรือสิ่งที่ฉันพลาดเพื่อให้ databae-updates เพิ่มตารางโดยอัตโนมัติ

เอกสารประกอบของ hook_update_N () ไม่ได้อธิบายอะไรเกี่ยวกับการแนะนำตารางใหม่ในขณะที่เอกสารของhook_schema() says:

ตารางที่ประกาศโดย hook นี้จะถูกสร้างขึ้นโดยอัตโนมัติเมื่อเปิดใช้งานโมดูลเป็นครั้งแรกและจะถูกลบออกเมื่อถอนการติดตั้งโมดูล

(ไฮไลท์เป็นของฉัน)

และถ้าเป็นเช่นนั้นวิธีที่ดีที่สุดในการหลีกเลี่ยงการทำซ้ำคำจำกัดความสคีมาสำหรับตารางใหม่ในทั้ง hook_update_N () และ hook_schema () เพียงอ้างถึงสคีมาดังต่อไปนี้:

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

ดูเหมือนว่าจะทำงาน แต่ในการเปลี่ยนตารางอีกครั้งจะล้มเหลวหากผู้ใช้เรียกใช้การปรับปรุงและได้รับการทำงานอย่างน้อยสอง hook_update_N () s หลังจากทั้งหมด: hook_update_N แรกจะติดตั้งฐานข้อมูลที่ถูกต้องแล้วและ hook_update_M ตัวที่สอง () จะพยายามเพิ่ม / เปลี่ยน / แก้ไขคอลัมน์ที่ทันสมัยอยู่แล้ว

คุณจัดการกับสิ่งนี้ได้อย่างไร


อ้างถึงdrupal.org/node/150215สำหรับเอกสารประกอบ ดังนั้นโดยทั่วไปในการเพิ่มตารางใหม่หลังจากติดตั้งโมดูลคือผ่าน hook_update_N แต่คุณยังเพิ่มคำจำกัดความของตารางไปที่ hook_schema สำหรับผู้ใช้ใหม่หรือติดตั้งใหม่ ดังนั้นรวมมันถ้าคุณทำการเปลี่ยนแปลงตารางใด ๆ เพื่ออัปเดตตารางปัจจุบันผ่าน hook_update_N แต่คุณรวมการเปลี่ยนแปลงใน hook_schema
Junedkazi

1
ดังนั้นจึงไม่มีวิธีหลีกเลี่ยงการละเมิด DRY ดูเหมือนว่า สงสาร
berkes

ไม่มีอะไรที่ฉันรู้ แต่คุณสามารถเขียนฟังก์ชั่นขนาดเล็กซึ่งมีคำจำกัดความสคีมาและเรียกคำจำกัดความนั้นในทั้งสองฟังก์ชั่น
Junedkazi

@berkes One สามารถกำหนดฟังก์ชั่นอื่นที่ส่งกลับสกีมาเพิ่มเติมและอ้างอิงทั้งในการอัพเดทและการติดตั้ง hooks
user1359

คำตอบ:


15

ดังนั้นเพียงคัดลอกวางจาก drupal.org คุณต้องเพิ่มคำจำกัดความของ schema ลงใน 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']);
}

คุณหมายความว่าไม่มีวิธีอื่นแล้วคัดลอกคำนิยามตารางจาก hook_schema () ลงใน hook_update_N () กล่าวอีกนัยหนึ่ง: ไม่มีวิธีใดที่จะหลีกเลี่ยงการละเมิด DRY ได้หรือไม่
berkes

3
@berkes จุดที่ ... มีคำอธิบายที่ดีมากว่าทำไมที่นี่ในกรณีที่คุณไม่ได้เห็นแล้วมัน
ไคลฟ์

@Clive นั่นเป็นตัวอย่างที่ยอดเยี่ยม ไม่เคยเห็นมาก่อน +1
Junedkazi

@junedkazi มีลิงก์ไปยังลิงก์ที่คุณให้ไว้ในความคิดเห็นของคุณ;)
Clive

-2

mymodule_update_7101 () เป็นสิ่งที่ดีพร้อมกับเบ็ดนี้ถ้าเราเพิ่ม hook_install () เพื่อดำเนินการเหมือนกันในขณะที่การติดตั้งโมดูลแทนการกำหนด hook_schema () ยังใช้งานได้สำหรับฉัน


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


มันเป็นวิธีปฏิบัติที่ดีกว่าของ Drupal ในการใช้ API ตามที่กำหนดไว้ ใช้ hook_schema () และ hook_update_N () โดยตรง สิ่งหนึ่งที่ฉันทำคือเรียกการใช้งาน hook_schema ของโมดูลของฉันใน hook_update_N () แล้วเรียกใช้ฟังก์ชัน db_ * ที่เกี่ยวข้อง
mradcliffe

hook_install()ไม่ควรเรียกใช้งาน hook_update_N () ใด ๆ เพื่อความจริง: hook_install()สำหรับการติดตั้งโมดูลเป็นครั้งแรกซึ่งหมายความว่าไม่มีตารางที่จะอัปเดต นอกจากนี้รหัสของคุณจะไม่สามารถใช้งานได้กับการอัปเดตที่ต้องมีชุดการทำงาน
kiamlaluno

ข้อมูลโค้ดนี้จะมีประโยชน์หากคุณกำลังอัพเดตสกีมาและเพื่อวัตถุประสงค์ในการปรับใช้เท่านั้น สำหรับระบบถ่ายทอดสดที่มีอยู่ไม่สามารถใช้งานได้
Akhila V Nair
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.