11

Can anyone help me to setup connection with multiple databases connection in Drupal 8? I have database on the same server and I want to access it along with default Drupal 8 database.

  • Add the database information into your settings.php file and you can switch into different database by using drupal.org/node/2204083 – user21641 Aug 3 '15 at 20:50
  • Hi @IvanJaros please consider adding this as an answer since it does answer the question. – digital Aug 4 '15 at 22:15
12

This is done in the same way as in Drupal 7, you can add the database credentials in your settings.php file.

$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',
);

You will now have two connection options, default and external. You can switch between them using:

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

// Switch back
\Drupal\Core\Database\Database::setActiveConnection();
  • Where would you be making these switches... from local to production for instance. – TikaL13 Sep 12 '16 at 20:57
  • @TikaL13 You switch when you need to fetch/put data from/to external source and you switch back when you are done with the fetch/put. – googletorp Sep 13 '16 at 12:59
  • @googletorp When external database is not available than got internal server error 500. IDK drupal trying to make connection at bootstrap or what. How can make quit gracefully? Thanks a lot – Mudassar Ali Sep 20 '16 at 14:53
  • @MudassarAli You might be able to do something in a try/catch statement where you actually switch database. It's not an error I'm familiar with though so not sure what happens – googletorp Sep 20 '16 at 15:23
  • Changing the active connection is not necessary. Instead, use Database::getConnection('external') and avoid messing with global state. – Pierre Buyle Sep 20 '16 at 17:25
5

In addition to retrieving a database connection to the external database using Database::getConnection(), you can also use dependency injection in your code to retrieve the connection as a dependency and declare your connection in a module's services YAML file:

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']
  • This is a nice trick, but requires you to actually do the queries yourself. This wont work if you need to let Drupal internal functions do stuff like loading entities and saving entities. (Fx if sites has shared content types) – googletorp Sep 26 '16 at 10:10
  • Drupal's DB is managed by Drupal itself, the entity system manage most of your content tables. Drupal is not made to share content at the database level. Doing so seems very fragile (ie. i depends on too many things you can't control). Even in alpha, something like drupal.org/project/replication seems much safer. – Pierre Buyle Sep 26 '16 at 12:19
  • 1
    This is an excellent solution, but I noticed that at least as of 8.3 you need to provide two parameters to the connection factory in the reverse order than I expected: arguments: ['default', 'external'] – acrosman Jul 19 '17 at 16:53
2

thank you very much, @googletorp!

here's a slightly more complete example - my code to select users from a D7 database who have created nodes:

\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();

Not the answer you're looking for? Browse other questions tagged or ask your own question.