Jak określić, w której bazie danych powinien zostać utworzony mój schemat?

12

Kiedy mogę używać wielu baz danych w Drupal 7, jak mogę określić, że tabela ma być tworzona w innej bazie danych na innym serwerze?

Domyślnie podczas instalowania modułu Drupal zakłada, że ​​wszystko w hook_schema()powinno być zainstalowane w domyślnej bazie danych. Czy istnieje sposób, aby określić, że tabela powinna zostać utworzona w innej bazie danych, czy istnieje jakiś sposób ręcznego obejścia, którego mogę użyć?

mikl
źródło
Początkowo sądzę, że nie można tego zrobić na poziomie interfejsu API. Powodem jest to, że moduł byłby powiązany z określoną i rzadką konfiguracją bazy danych. Zakładam, że jest to moduł specyficzny dla witryny? Uważam, że twoja poprawka będzie musiała również dotyczyć konfiguracji witryny / bazy danych.
Letharion

Odpowiedzi:

4

Nie sądzę, że istnieje oficjalny interfejs API; ogólnie nie ma sensu robić tego.

To powiedziawszy, wszystko co musisz zrobić, to nadać swoją hook_schemainną nazwę niż yourmodule_schema(w zasadzie cokolwiek chcesz, jak yourmodule_schema_otherdb), a następnie w hook_install (), najpierw przełącz bazę danych , a następnie zreplikuj to, co robi drupal_install_schema () , z wyjątkiem tego, że wywołujesz niestandardową definicję schematu funkcji, a następnie przełącz bazę danych z powrotem na domyślną.

Pamiętaj też o wdrożeniu hook_uninstall().

Nie mam jednak pojęcia, dlaczego chcesz to zrobić. :)

Berdir
źródło
Celem (w tym przypadku) jest sharding, ale mogę wymyślić wiele ważnych powodów, dla których byś to zrobił. Biorąc pod uwagę, jak wiele kłopotów miałoby to obejście tego problemu, myślę, że skończę po prostu pisząc o tym wiele CREATE TABLEstwierdzeń.
mikl
Dla których musisz również napisać odpowiedni hook_uninstall (), jeśli chcesz to zrobić poprawnie :) Nie jestem pewien, czy widzę problemy, o których mówisz, wszystko co musisz zrobić, to wdrożyć hook_enable (co musiałeś zrobić w 6 .x również) i skopiuj i dostosuj kilka wierszy kodu w drupal_install_schema (). Zwłaszcza jeśli chcesz, aby tabele były wyświetlane w wielu bazach danych, możesz nawet użyć hook_schema (), aby mieć go w domyślnej bazie danych, a w hook_install () zrobić to również dla innych baz danych. Być może będziesz w stanie po prostu wywołać schemat_instalacji_drupal ($ yourmodule) pomiędzy przełączaniem bazy danych.
Berdir,
11

Osiągnąłem to dzięki informacjom dostarczonym przez Berdir . Mój kod wygląda następująco:

<?php
function mymodule_schema_otherdb() {
  $schema['mytable'] = array(
    'description' => 'My table description',
    'fields' => array(
      'myfield' => array(
        'description' => 'My field description',
        'type' => 'serial',
        'size' => 'medium',
        'not null' => TRUE,
        'unsigned' => TRUE,
      ),
    ),
    'primary key' => array('myfield'),
  );
  return $schema;
}

function mymodule_install() {
  db_set_active('otherdb');
  $schema = mymodule_schema_otherdb();
  foreach ($schema as $name => $table) {
    db_create_table($name, $table);
  }
  db_set_active();
}

function mymodule_uninstall() {
  db_set_active('otherdb');
  $schema = mymodule_schema_otherdb();
  foreach ($schema as $name => $table) {
    db_drop_table($name);
  }
  db_set_active();
}
Елин Й.
źródło
Nie byłoby zbyt dużo pracy, aby uzyskać moduł, który szuka tego zaczepu i uruchamia się podczas instalacji i odinstalowywania. gdzie inny db jest kluczem struktury schematu
Jeremy French
@JeremyFrench, czy ta konfiguracja wymaga wcześniejszego utworzenia pustej bazy danych? Tak zakładam.
zkent
1

Wersja Drupala 8 kodu pliku * .install dostarczonego przez @ Елин Й .:

Uwaga: Baza danych musi istnieć i zostać określona w pliku settings.php.

<?php
function mymodule_schema_otherdb() {
  $schema['mytable'] = array(
    'description' => 'My table description',
    'fields' => array(
      'myfield' => array(
        'description' => 'My field description',
        'type' => 'serial',
        'size' => 'medium',
        'not null' => TRUE,
        'unsigned' => TRUE,
      ),
    ),
    'primary key' => array('myfield'),
  );
  return $schema;
}

/**
 * Implements hook_install().
 */
function mymodule_install() {
  \Drupal\Core\Database\Database::setActiveConnection('otherdb');
  $connection = \Drupal\Core\Database\Database::getConnection();

  $schema = mymodule_schema_shared();
  foreach ($schema as $name => $table) {
    $connection->schema()->createTable($name, $table);
  }

  \Drupal\Core\Database\Database::setActiveConnection();
}

/**
 * Implements hook_uninstall().
 */
function mymodule_uninstall() {
  \Drupal\Core\Database\Database::setActiveConnection('otherdb');
  $connection = \Drupal\Core\Database\Database::getConnection();

  $schema = mymodule_schema_shared();
  foreach ($schema as $name => $table) {
    $connection->schema()->dropTable($name);
  }

  \Drupal\Core\Database\Database::setActiveConnection();
}

Oto sedno .

inne maszyny
źródło
-2

W Settings.php
$db_url=array('default'=>$db_url, 'sec_db'=>$sec_db_url);
In hook_schema db_set_active('sec_db')połączy się teraz z innym DB, nie jestem pewien, czy jest to zalecane, czy też nie wypróbuj go na własne ryzyko. I można użyć przedrostka db_prefix do zapytania z tego dodatkowego DB. Możesz użyć przedrostka db w pliku settings.php

GoodSp33d
źródło
Byłoby to jednak obejmujące cały system, co OP może już zrobić
Clive
co byłoby w całym systemie? proszę wyjaśnić
GoodSp33d,
1
Te (semantyka $db_url, $db_prefixjako ustawienie globalne są dla Drupal 6. I kropka-notacja działa tylko w przypadku korzystania z innej bazy danych na tym samym serwerze MySQL, a nie kiedy (jak w moim przypadku) masz dostęp do różnych serwerów.
Mikl
@kantu OP pyta, jak zmienić bazę danych dla określonej tabeli. Twoje oryginalne rozwiązanie (przed edycją) wprowadziłoby zmiany w całym systemie, a nie w poszczególnych tabelach.
Clive
2
I jak wspomniałem wcześniej, w Drupal 7 nie ma żadnej zmiennej $db_urlglobalnej $db_prefix, a nawet gdyby tak było, nie rozwiązałoby to problemu.
mikl