Come faccio a specificare in quale database deve essere creato il mio schema?


12

Quando si utilizzano più database in Drupal 7, come posso specificare che una tabella deve essere creata in un database diverso su un server diverso?

Per impostazione predefinita, quando si installa un modulo, Drupal presuppone che tutto ciò che hook_schema()deve essere installato sia nel database predefinito. Esiste un modo per specificare che una tabella deve essere creata su un database diverso o esiste un tipo di soluzione manuale che posso usare?


Il mio pensiero iniziale è che non puoi farlo a livello di API. Il motivo è che il tuo modulo sarebbe legato a una specifica e rara configurazione del database. Presumo che questo sia un modulo specifico del sito? Credo che anche la tua correzione debba essere specifica per la configurazione del sito / db.
Letharion,

Risposte:


4

Non penso che ci sia un'API ufficiale; non ha molto senso farlo in generale.

Detto questo, tutto ciò che devi fare è dare al tuo hook_schemanome un nome diverso da yourmodule_schema(praticamente qualunque cosa tu voglia, come yourmodule_schema_otherdb) e poi in hook_install (), prima cambia il tuo database , quindi replica ciò che fa drupal_install_schema () tranne che chiami la definizione del tuo schema personalizzato funzione e quindi ripristinare il database al valore predefinito.

Inoltre, ricorda di implementare hook_uninstall().

Non ho idea del perché tu voglia farlo, però. :)


Lo scopo (in questo caso) è lo sharding, ma posso pensare a molte valide ragioni per cui lo faresti. Dati i guai che avrebbe risolto questo problema, penso che finirò per scrivere solo una serie di CREATE TABLEdichiarazioni per questo.
mikl

Per cui dovrai scrivere il corrispondente hook_uninstall () anche se vuoi farlo correttamente :) Non sono sicuro di vedere i problemi di cui stai parlando, tutto ciò che devi fare è implementare hook_enable (che dovevi fare in 6 .x) e copia e modifica le poche righe di codice in drupal_install_schema (). Soprattutto se vuoi che le tue tabelle vengano mostrate in più database, puoi anche usare hook_schema () per averlo nel database predefinito e in hook_install () farlo anche per gli altri database. Potresti anche essere in grado di chiamare semplicemente drupal_install_schema ($ yourmodule) tra il cambio del db.
Berdir,

11

L'ho raggiunto con le informazioni fornite da Berdir . Il mio codice è simile a:

<?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();
}

Non sarebbe troppo lavoro per ottenere un modulo che cerca quel gancio e si attiva durante l'installazione e la disinstallazione. con altri db che sono una chiave della struttura dello schema
Jeremy French

@JeremyFrench, questa configurazione richiede la creazione anticipata del database vuoto? Sto assumendo così.
zkent,

1

Una versione Drupal 8 del codice file * .install fornito da @ Елин Й .:

Nota: il database deve esistere ed essere specificato in 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();
}

Ecco un Gist .


-2

In Settings.php
$db_url=array('default'=>$db_url, 'sec_db'=>$sec_db_url);
In hook_schema db_set_active('sec_db')ora si connetterà al tuo altro DB, non sono sicuro se questo è consigliato o non provarlo a proprio rischio. E puoi usare db_prefix per eseguire query da questo DB secondario. Puoi usare il prefisso db in settings.php


Sarebbe comunque a livello di sistema, cosa che l'OP può già fare
Clive

quale sarebbe il sistema a livello? per favore chiarisci
GoodSp33d

1
Queste semantiche ( $db_url, $db_prefixcome impostazione globale sono per Drupal 6. E la notazione a punti funziona solo quando si utilizza un database diverso sullo stesso server MySQL, non quando (come nel mio caso) si accede a server diversi.
mikl

@kantu OP chiede come modificare il database per una tabella specifica. La soluzione originale (prima della modifica) avrebbe apportato la modifica a livello di sistema, non tabella per tabella.
Clive

2
E come ho detto prima, in Drupal 7 non esiste $db_urluna $db_prefixvariabile globale e, anche se ci fosse, non risolverebbe il problema.
mikl
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.