Como especifico em qual banco de dados meu esquema deve ser criado?

12

Ao usar vários bancos de dados no Drupal 7, como posso especificar que uma tabela seja criada em um banco de dados diferente em um servidor diferente?

Por padrão, quando você instala um módulo, o Drupal assume que tudo hook_schema()deve estar instalado no banco de dados padrão. Existe uma maneira de especificar que uma tabela deve ser criada em um banco de dados diferente ou há algum tipo de solução manual que eu possa usar?

mikl
fonte
Meu pensamento inicial é que você não pode fazer isso no nível da API. A razão é que seu módulo estaria vinculado a uma configuração de banco de dados específica e rara. Presumo que este é um módulo específico do site? Acredito que sua correção também precisará ser específica do site / db-configuration.
Letharion

Respostas:

4

Eu não acho que exista uma API oficial; não faz muito sentido fazer isso em geral.

Dito isso, tudo o que você precisa fazer é dar hook_schemaum nome diferente do que yourmodule_schema(basicamente o que você quiser, como yourmodule_schema_otherdb) e, em hook_install (), primeiro alterne seu banco de dados e , em seguida, replique o que drupal_install_schema () faz, exceto que você chama sua definição de esquema personalizada função e, em seguida, alterne o banco de dados para o padrão.

Além disso, lembre-se de implementar hook_uninstall().

Mas não faço ideia por que você faria isso. :)

Berdir
fonte
O objetivo (neste caso) é fragmentar, mas posso pensar em vários motivos válidos pelos quais você faria isso. Dado o problema que seria contornar essa falha, acho que acabarei escrevendo apenas um monte de CREATE TABLEdeclarações para isso.
Mikl 6/03/12
Para o qual você precisará escrever hook_uninstall () correspondente também, se quiser fazê-lo corretamente :) Não tenho certeza de ver os problemas dos quais você está falando, tudo o que você precisa fazer é implementar hook_enable (o que você deve fazer em 6 .x) e copie e ajuste as poucas linhas de código em drupal_install_schema (). Especialmente se você deseja que suas tabelas apareçam em vários bancos de dados, você pode até usar hook_schema () para tê-lo no banco de dados padrão e em hook_install () para os outros bancos de dados também. Você pode até chamar simplesmente drupal_install_schema ($ yourmodule) entre alternar o db.
Berdir 6/03/12
11

Consegui isso com as informações fornecidas por Berdir . Meu código se parece com:

<?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();
}
Елин Й.
fonte
Não seria muito trabalhoso obter um módulo que procure por esse gancho e seja acionado na instalação e desinstalação. com outros db sendo uma chave da estrutura do esquema
Jeremy Francês
@ JeremyFrench, essa configuração exige que o banco de dados vazio seja criado com antecedência? Estou assumindo que sim.
zkent
1

UMA versão do Drupal 8 do código do arquivo * .install fornecida por @ Елин Й .:

Nota: O banco de dados deve existir e ser especificado em 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();
}

Aqui está uma essência .

outras máquinas
fonte
-2

Em Settings.php, o
$db_url=array('default'=>$db_url, 'sec_db'=>$sec_db_url);
In hook_schema db_set_active('sec_db')agora se conectará ao seu outro banco de dados, não tenho certeza se isso é recomendado ou não tente por sua conta e risco. E você pode usar o db_prefix para consultar esse banco de dados secundário. Você pode usar o prefixo db em settings.php

GoodSp33d
fonte
Isso seria um sistema amplo, porém, que o OP já pode fazer
Clive
o que seria todo o sistema? Por favor, esclareça
GoodSp33d 5/12
1
Estes semântica ( $db_url, $db_prefixcomo uma configuração global são para Drupal 6. E a notação de ponto só funciona quando se utiliza um banco de dados diferente no mesmo servidor MySQL, não quando (como no meu caso) que você está acessando servidores diferentes.
mikl
O @kantu OP está perguntando como alterar o banco de dados para uma tabela específica. Sua solução original (antes da edição) teria feito a alteração em todo o sistema, não em uma tabela por tabela.
Clive
2
E, como mencionei antes, não existe $db_urlou existe uma $db_prefixvariável global no Drupal 7 e, mesmo que houvesse, isso não resolveria o problema.
mikl