Các bảng mới phải được tạo trong hook_update_N ()?


11

Khi bạn tạo một bảng mới hook_schema(), bảng đó có nên được thêm vào hook_update_N()không? Hoặc có một số mẹo, hoặc một cái gì đó tôi đã bỏ lỡ, để cập nhật databae tự động thêm bảng?

Tài liệu của hook_update_N () không giải thích bất cứ điều gì về việc giới thiệu các bảng mới, trong khi tài liệuhook_schema() nói:

Các bảng được khai báo bởi hook này sẽ được tạo tự động khi mô-đun được bật lần đầu và được gỡ bỏ khi mô-đun được gỡ cài đặt.

(Nổi bật là của tôi)

Và nếu vậy, làm thế nào để tránh trùng lặp các định nghĩa lược đồ cho bảng mới trong cả hook_update_N () và hook_schema (). Chỉ cần tham khảo lược đồ như sau:

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

Có vẻ hoạt động, nhưng khi thay đổi bảng một lần nữa, sẽ thất bại nếu người dùng chạy các bản cập nhật và được chạy hai hoặc nhiều hook_update_N () s. Sau tất cả: hook_update_N đầu tiên sau đó sẽ cài đặt cơ sở dữ liệu chính xác và hook_update_M () thứ hai sẽ cố gắng thêm / thay đổi / thay đổi các cột đã được cập nhật.

Làm thế nào để bạn đối phó với điều này?


Tham khảo drupal.org/node/150215 để biết tài liệu. Vì vậy, về cơ bản để thêm một bảng mới sau khi mô-đun được cài đặt là thông qua hook_update_N nhưng bạn cũng thêm định nghĩa bảng vào hook_schema cho người dùng mới hoặc cài đặt mới. Vì vậy, tổng hợp lại nếu bạn thực hiện bất kỳ thay đổi bảng nào để cập nhật các bảng hiện tại thông qua hook_update_N nhưng bạn cũng hợp nhất các thay đổi trong hook_schema.
Junedkazi

1
Vì vậy, không có cách nào để tránh vi phạm DRY, dường như. Điều đáng tiếc.
berkes

không có gì mà tôi biết Nhưng bạn có thể viết một hàm nhỏ có định nghĩa lược đồ và gọi định nghĩa đó trong cả hai hàm.
Junedkazi

@berkes Người ta có thể định nghĩa một hàm khác trả về lược đồ bổ sung và tham chiếu đến nó trong cả móc cập nhật và cài đặt.
dùng1359

Câu trả lời:


15

Vì vậy, chỉ cần một bản sao dán từ drupal.org. Bạn cũng cần thêm định nghĩa lược đồ vào 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']);
}

Bạn có nghĩa là không có cách nào khác sau đó sao chép định nghĩa bảng từ hook_schema () vào hook_update_N (). Nói cách khác: rằng không có cách nào để tránh vi phạm DRY?
cập bến

3
@berkes phát hiện ra ... có một lời giải thích rất hay tại sao lại ở đây trong trường hợp bạn chưa thấy nó
Clive

@Clive Đó là một ví dụ tuyệt vời. Chưa bao giờ nhìn thấy nó trước đây. +1
Junedkazi

@junedkazi Có một liên kết đến liên kết mà bạn đã cung cấp trong nhận xét của mình;)
Clive

-2

mymodule_update_7101 () là tốt, cùng với hook này nếu chúng ta thêm hook_install () để thực hiện tương tự trong khi cài đặt mô-đun thay vì định nghĩa hook_schema () cũng hoạt động với tôi.


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


Việc sử dụng API theo hướng dẫn sẽ tốt hơn nhiều. Sử dụng trực tiếp hook_schema () và hook_update_N (). Một điều tôi làm là gọi hàm triển khai hook_schema của mô-đun của tôi trong hook_update_N (), rồi chạy các hàm db_ * tương ứng.
mradcliffe

hook_install()không nên gọi bất kỳ triển khai hook_update_N () nào, vì thực tế đơn giản: hook_install()là để cài đặt một mô-đun lần đầu tiên, điều đó có nghĩa là không có bảng để cập nhật. Ngoài ra, mã của bạn sẽ không hoạt động đối với các bản cập nhật cần một đợt để chạy.
kiamlaluno

Đoạn mã này sẽ hữu ích, nếu bạn đang cập nhật lược đồ và chỉ cho mục đích triển khai. Đối với một hệ thống sống hiện có, điều này không thể được sử dụng.
Akhila V Nair
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.