複数のデータベース接続をセットアップするにはどうすればよいですか?


12

Drupal 8で複数のデータベース接続との接続をセットアップするのを手伝ってくれる人はいますか?同じサーバーにデータベースがあり、デフォルトのDrupal 8データベースと一緒にアクセスしたい。


データベース情報をsettings.phpファイルに追加すると、drupal.org

こんにちは@IvanJarosは質問に回答するので、これを回答として追加することを検討してください。
デジタル

回答:


13

これは、Drupal 7と同じ方法で行われます。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',
);

これで、デフォルトと外部の2つの接続オプションが表示されます。以下を使用してそれらを切り替えることができます。

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

// Switch back
\Drupal\Core\Database\Database::setActiveConnection();

これらの切り替えはどこで行いますか?たとえばローカルから本番に切り替えます。
TikaL13 2016

@ TikaL13外部ソースとの間でデータをフェッチ/出力する必要があるときに切り替え、フェッチ/出力が完了したら元に戻します。
googletorp

@googletorp外部データベースが利用できない場合、内部サーバーエラー500が発生します。IDKdrupalがブートストラップまたは何で接続しようとしています。どのようにして優雅に辞めることができますか?
どうも

@MudassarAli実際にデータベースを切り替えるtry / catchステートメントで何かを実行できる場合があります。私がよく知っているエラーではありませんが、何が起こるか
わかり

1
アクティブな接続を変更する必要はありません。代わりに、Database::getConnection('external')グローバルな状態をいじって使用しないでください。
Pierre Buyle 2016

5

を使用して外部データベースへのデータベース接続を取得するだけでなく、コードで依存性注入を使用して、接続を依存関係として取得し、モジュールのサービスYAMLファイルで接続を宣言するDatabase::getConnection()こともできます。

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']

これは素晴らしいトリックですが、クエリを実際に自分で行う必要があります。Drupalの内部関数にエンティティのロードやエンティティの保存などをさせる必要がある場合、これは機能しません。(サイトでコンテンツタイプが共有されている場合はFx)
googletorp

DrupalのDBはDrupal自体によって管理され、エンティティシステムはほとんどのコンテンツテーブルを管理します。Drupalはデータベースレベルでコンテンツを共有するように作られていません。そうすることは非常に壊れやすいようです(つまり、私はあなたが制御できない多くのことに依存しています)。アルファ版でも、drupal.org / project / replicationのようなものははるかに安全に見えます。
Pierre Buyle 16

1
これは優れた解決策ですが、少なくとも8.3では、接続ファクトリーに2つのパラメーターを予想とは逆の順序で指定する必要があることに気付きました。引数:['default'、 'external']
acrosman

2

@googletorp、どうもありがとうございました。

これはもう少し完全な例です-ノードを作成したD7データベースからユーザーを選択するためのコード:

\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();
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.