¿Cómo especifico en qué base de datos se debe crear mi esquema?

12

Al usar varias bases de datos en Drupal 7, ¿cómo puedo especificar que se cree una tabla en una base de datos diferente en un servidor diferente?

Por defecto, cuando instala un módulo, Drupal asume que todo hook_schema()debe estar instalado en la base de datos predeterminada. ¿Hay alguna manera de especificar que se debe crear una tabla en una base de datos diferente, o hay algún tipo de solución manual que pueda usar?

mikl
fuente
Mi pensamiento inicial es que no puedes hacer esto a nivel API. La razón es que su módulo estaría vinculado a una configuración de base de datos específica y rara. Supongo que este es un módulo específico del sitio? Creo que su solución también deberá ser específica del sitio / configuración de base de datos.
Letharion

Respuestas:

4

No creo que haya una API oficial; No tiene mucho sentido hacer esto en general.

Dicho esto, todo lo que necesita hacer es darle hook_schemaun nombre diferente a yourmodule_schema(básicamente lo que quiera, como yourmodule_schema_otherdb) y luego en hook_install (), primero cambie su base de datos , luego replique lo que hace drupal_install_schema () excepto que llama a su definición de esquema personalizada función y luego cambie la base de datos al valor predeterminado.

Además, recuerde implementar hook_uninstall().

Sin embargo, no tengo idea de por qué querrías hacer esto. :)

Berdir
fuente
El propósito (en este caso) es fragmentar, pero puedo pensar en muchas razones válidas para que lo haga. Dada la cantidad de problemas que se resolverían con esta deficiencia, creo que terminaré escribiendo un montón de CREATE TABLEdeclaraciones para esto.
mikl
Para lo cual también deberá escribir hook_uninstall () correspondiente si desea hacerlo correctamente :) No estoy seguro de ver los problemas de los que está hablando, todo lo que necesita hacer es implementar hook_enable (que tuvo que hacer en 6 .x también) y copie y ajuste las pocas líneas de código en drupal_install_schema (). Especialmente si desea que sus tablas se muestren en varias bases de datos, incluso puede usar hook_schema () para tenerlo en la base de datos predeterminada y en hook_install () también para las otras bases de datos. Incluso podría simplemente llamar a drupal_install_schema ($ yourmodule) entre cambiar la base de datos.
Berdir
11

Lo he logrado con la información proporcionada por Berdir . Mi código se ve así:

<?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();
}
Елин Й.
fuente
No sería demasiado trabajo obtener un módulo que busque ese gancho y se dispare durante la instalación y desinstalación. con otro db como clave de la estructura del esquema
Jeremy French
@JeremyFrench, ¿esta configuración requiere que la base de datos vacía se cree de antemano? Estoy suponiendo que sí.
zkent
1

Una versión Drupal 8 del código de archivo * .install proporcionado por @ Елин Й .:

Nota: La base de datos debe existir y especificarse en 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();
}

Aquí hay una esencia .

otras maquinas
fuente
-2

En Settings.php
$db_url=array('default'=>$db_url, 'sec_db'=>$sec_db_url);
In hook_schema db_set_active('sec_db')ahora se conectará a su otra base de datos, no estoy seguro de si esto se recomienda o no lo intente bajo su propio riesgo. Y puede hacer uso de db_prefix para consultar desde este DB secundario. Puedes usar el prefijo db en settings.php

GoodSp33d
fuente
Sin embargo, eso sería todo el sistema, que el OP ya puede hacer
Clive
¿Cuál sería todo el sistema? por favor aclare
GoodSp33d
1
Esta semántica ( $db_url, $db_prefixcomo una configuración global son para Drupal 6. Y el punto-notación sólo funciona cuando se utiliza una base de datos diferente en el mismo servidor MySQL, no cuando (como en mi caso) que está accediendo diferentes servidores.
mikl
@kantu OP pregunta cómo cambiar la base de datos para una tabla específica. Su solución original (antes de editar) habría realizado el cambio en todo el sistema, no tabla por tabla.
Clive
2
Y como mencioné antes, no hay $db_urluna $db_prefixvariable global o ninguna en Drupal 7, e incluso si la hubiera, no resolvería el problema.
mikl