Comment spécifier dans quelle base de données mon schéma doit être créé?

12

Lors de l'utilisation de plusieurs bases de données dans Drupal 7, comment puis-je spécifier qu'une table doit être créée dans une base de données différente sur un serveur différent?

Par défaut, lorsque vous installez un module, Drupal suppose que tout hook_schema()doit être installé dans la base de données par défaut. Existe-t-il un moyen de spécifier qu'une table doit être créée sur une base de données différente, ou existe-t-il une sorte de solution de contournement manuelle que je peux utiliser?

mikl
la source
Ma pensée initiale est que vous ne pouvez pas le faire au niveau de l'API. La raison étant que votre module serait lié à une configuration de base de données spécifique et rare. Je suppose que c'est un module spécifique au site? Je pense que votre correctif devra également être spécifique à la configuration du site / db.
Letharion

Réponses:

4

Je ne pense pas qu'il existe une API officielle; cela n'a pas beaucoup de sens de le faire en général.

Cela dit, tout ce que vous devez faire est de vous donner hook_schemaun nom différent de yourmodule_schema(essentiellement ce que vous voulez, comme yourmodule_schema_otherdb), puis dans hook_install (), changez d' abord votre base de données , puis répliquez ce que drupal_install_schema () fait, sauf que vous appelez votre définition de schéma personnalisé fonction, puis revenir à la base de données par défaut.

N'oubliez pas non plus de mettre en œuvre hook_uninstall().

Mais je ne sais pas pourquoi vous voudriez faire ça. :)

Berdir
la source
Le but (dans ce cas) est le partage, mais je peux penser à de nombreuses raisons valables pour lesquelles vous feriez cela. Compte tenu de la difficulté que cela entraînerait à contourner cette lacune, je pense que je finirai par écrire une foule de CREATE TABLEdéclarations à ce sujet.
mikl
Pour lequel vous devrez également écrire hook_uninstall () si vous voulez le faire correctement :) Je ne suis pas sûr de voir les problèmes dont vous parlez, tout ce que vous devez faire est d'implémenter hook_enable (ce que vous avez dû faire en 6 .x également) et copiez et ajustez les quelques lignes de code dans drupal_install_schema (). Surtout si vous souhaitez que vos tables apparaissent dans plusieurs bases de données, vous pouvez même utiliser hook_schema () pour les avoir dans la base de données par défaut et dans hook_install () le faire pour les autres bases de données également. Vous pourriez même être en mesure d'appeler simplement drupal_install_schema ($ yourmodule) entre les changements de db.
Berdir
11

J'y suis parvenu grâce aux informations fournies par Berdir . Mon code ressemble à:

<?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();
}
Елин Й.
la source
Ce ne serait pas trop de travail pour obtenir un module qui recherche ce crochet et se déclenche lors de l'installation et de la désinstallation. avec un autre db étant une clé de la structure du schéma
Jeremy French
@JeremyFrench, cette configuration nécessite-t-elle que la base de données vide soit créée à l'avance? Je suppose que oui.
zkent
1

Une version Drupal 8 du code de fichier * .install fourni par @ Елин Й .:

Remarque: la base de données doit exister et être spécifiée dans 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();
}

Voici un résumé .

autresmachines
la source
-2

Dans Settings.php
$db_url=array('default'=>$db_url, 'sec_db'=>$sec_db_url);
In hook_schema db_set_active('sec_db')va maintenant se connecter à votre autre base de données, ne savez pas si cela est recommandé ou ne l'essayez pas à vos risques et périls. Et vous pouvez utiliser db_prefix pour interroger à partir de cette base de données secondaire. Vous pouvez utiliser le préfixe db dans settings.php

GoodSp33d
la source
Ce serait cependant à l'échelle du système, ce que le PO peut déjà faire
Clive
quelle serait l'ensemble du système? veuillez clarifier
GoodSp33d
1
Ces sémantiques ( $db_url, $db_prefixcomme un paramètre global sont pour Drupal 6. Et la notation par points ne fonctionne que lorsque vous utilisez une base de données différente sur le même serveur MySQL, pas quand (comme dans mon cas) vous accédez à différents serveurs.
mikl
@kantu OP demande comment changer la base de données pour une table spécifique. Votre solution d'origine (avant la modification) aurait effectué la modification à l'échelle du système, et non pas table par table.
Clive
2
Et comme je l'ai mentionné précédemment, il n'y a pas $db_urlou une $db_prefixvariable globale dans Drupal 7, et même s'il y en avait, cela ne résoudrait pas le problème.
mikl