Jak mogę skonfigurować wiele połączeń z bazą danych?

12

Czy ktoś może mi pomóc skonfigurować połączenie z wieloma bazami danych w Drupal 8? Mam bazę danych na tym samym serwerze i chcę uzyskać do niej dostęp wraz z domyślną bazą danych Drupal 8.

Mudassar Ali
źródło
Dodaj informacje o bazie danych do pliku settings.php i możesz przejść do innej bazy danych, używając drupal.org/node/2204083
Cześć @IvanJaros, proszę rozważyć dodanie tego jako odpowiedzi, ponieważ odpowiada ono na pytanie.
cyfrowe

Odpowiedzi:

13

Odbywa się to w taki sam sposób, jak w Drupal 7, możesz dodać poświadczenia bazy danych do pliku settings.php.

$databases['default']['default'] = array(
  'database' => 'drupal8',
  'username' => 'username',
  'password' => 'password',
  'prefix' => '',
  'host' => 'localhost',
  'port' => '3306',
  'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
  'driver' => 'mysql',
);

$databases['external']['default'] = array(
  'database' => 'external',
  'username' => 'username',
  'password' => 'password',
  'prefix' => '',
  'host' => 'localhost',
  'port' => '3306',
  'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
  'driver' => 'mysql',
);

Będziesz teraz mieć dwie opcje połączenia, domyślną i zewnętrzną. Możesz przełączać się między nimi za pomocą:

// Switch to external database
\Drupal\Core\Database\Database::setActiveConnection('external');
// Do queries...

// Switch back
\Drupal\Core\Database\Database::setActiveConnection();
googletorp
źródło
Gdzie miałbyś dokonać tych zmian ... na przykład z lokalnego na produkcyjny.
TikaL13,
@ TikaL13 Przełączasz się, gdy potrzebujesz pobrać / umieścić dane ze / do źródła zewnętrznego i przełączasz się z powrotem, gdy skończysz pobieranie / put.
googletorp
@googletorp Gdy zewnętrzna baza danych nie jest dostępna, dostał wewnętrzny błąd serwera 500. IDK drupal próbuje nawiązać połączenie podczas bootstrapu lub co tam. Jak sprawić, by rzucić wdzięku?
Wielkie
@MudassarAli Możesz zrobić coś w instrukcji try / catch, w której faktycznie przełączasz bazę danych. Nie znam tego błędu, ale nie jestem pewien, co się stanie
googletorp
1
Zmiana aktywnego połączenia nie jest konieczna. Zamiast tego używaj Database::getConnection('external')i unikaj bałaganu ze stanem globalnym.
Pierre Buyle,
5

Oprócz pobierania połączenia bazy danych z zewnętrzną bazą danych za pomocą Database::getConnection(), możesz również użyć wstrzykiwania zależności w kodzie, aby pobrać połączenie jako zależność i zadeklarować połączenie w pliku YAML usług modułu:

database.external:
  class: Drupal\Core\Database\Connection
  factory: 'Drupal\Core\Database\Database::getConnection'
  arguments: ['external']

external_database_dependent_service:
  class: Drupal\MODULE\Some\Class\For\A\ServiceUsingTheExternalDatabase
  arguments: ['@database.external']
Pierre Buyle
źródło
To fajna sztuczka, ale wymaga samodzielnego wykonania zapytań. To nie zadziała, jeśli musisz pozwolić wewnętrznym funkcjom Drupala robić takie rzeczy jak ładowanie encji i zapisywanie encji. (Fx, jeśli witryny mają wspólne typy treści)
googletorp
Bazą danych Drupala zarządza sam Drupal, system encji zarządza większością twoich tabel treści. Drupal nie jest przeznaczony do udostępniania treści na poziomie bazy danych. Wydaje się to bardzo delikatne (tzn. Zależy od zbyt wielu rzeczy, których nie można kontrolować). Nawet w wersji alfa coś takiego jak drupal.org/project/replication wydaje się znacznie bezpieczniejsze.
Pierre Buyle,
1
Jest to doskonałe rozwiązanie, ale zauważyłem, że przynajmniej od 8.3 musisz podać fabryce połączeń dwa parametry w odwrotnej kolejności niż się spodziewałem: argumenty: [„default”, „external”]
acrosman
2

dziękuję bardzo, @googletorp!

oto nieco bardziej kompletny przykład - mój kod do wybierania użytkowników z bazy danych D7, którzy utworzyli węzły:

\Drupal\Core\Database\Database::setActiveConnection('external');

// Get a connection going
$db = \Drupal\Core\Database\Database::getConnection();

$query = $db->select('users', 'u');
$query->fields('u', array('uid', 'name'));
$query->join('node', 'n', 'n.uid = u.uid');
$query->orderBy('uid');
$users = $query->execute()->fetchAllKeyed();

\Drupal\Core\Database\Database::setActiveConnection();
Lucoweb
źródło