Как мне указать, в какой базе данных должна быть создана моя схема?

12

При использовании нескольких баз данных в Drupal 7, как я могу указать, что таблица должна создаваться в другой базе данных на другом сервере?

По умолчанию при установке модуля Drupal предполагает, что все в hook_schema()должно быть установлено в базе данных по умолчанию. Есть ли способ указать, что таблица должна создаваться в другой базе данных, или я могу использовать какой-то ручной обход?

Mikl
источник
Сначала я думал, что вы не можете сделать это на уровне API. Причина в том, что ваш модуль будет привязан к определенной и редкой конфигурации базы данных. Я предполагаю, что это модуль для конкретного сайта? Я считаю, что ваше исправление также должно быть привязано к конкретной конфигурации сайта / базы данных.
Летарион

Ответы:

4

Я не думаю, что есть официальный API; в общем нет смысла делать это.

Тем не менее, все, что вам нужно сделать, это дать hook_schemaдругое имя, отличное от yourmodule_schema(в основном то, что вы хотите, например yourmodule_schema_otherdb), а затем в hook_install () сначала переключить базу данных , а затем повторить то, что делает drupal_install_schema () , за исключением того, что вы вызываете определение своей пользовательской схемы. функции, а затем переключите базу данных обратно на значение по умолчанию.

Кроме того, не забудьте реализовать hook_uninstall().

Не знаю, почему вы хотите это сделать, хотя. :)

Berdir
источник
Целью (в данном случае) является осколок, но я могу придумать множество веских причин, по которым вы это сделаете. Учитывая, как много проблем будет работать с этим недостатком, я думаю, что в итоге я просто напишу кучу CREATE TABLEзаявлений для этого.
Mikl
Для чего вам нужно будет написать соответствующую функцию hook_uninstall (), если вы хотите сделать это правильно :) Не уверен, что я вижу проблемы, о которых вы говорите, все, что вам нужно сделать, это реализовать hook_enable (что вы должны были сделать в 6 .x), скопируйте и измените несколько строк кода в drupal_install_schema (). Особенно, если вы хотите, чтобы ваши таблицы отображались в нескольких базах данных, вы даже можете использовать hook_schema (), чтобы сделать это в базе данных по умолчанию, а в hook_install () сделать это и для других баз данных. Вы даже можете просто вызывать drupal_install_schema ($ yourmodule) между переключением базы данных.
Бердир
11

Я добился этого благодаря информации, предоставленной Бердиром . Мой код выглядит так:

<?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();
}
Елин Й.
источник
Не было бы слишком много работы, чтобы получить модуль, который ищет этот хук и запускается при установке и удалении. с другим БД, являющимся ключом структуры схемы
Джереми Френч
@JeremyFrench, требует ли эта настройка заблаговременного создания пустой базы данных? Я так предполагаю.
zkent
1

Drupal 8 версии * .install файл код , предоставленный @ Елин .: Я

Примечание. База данных должна существовать и указываться в файле 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();
}

Вот Гист .

othermachines
источник
-2

В Settings.php
$db_url=array('default'=>$db_url, 'sec_db'=>$sec_db_url);
In hook_schema db_set_active('sec_db')теперь будет подключаться к вашей другой БД, не уверен, рекомендуется ли это или не пытайтесь на свой страх и риск. И вы можете использовать db_prefix для запроса из этой вторичной БД. Вы можете использовать префикс db в settings.php

GoodSp33d
источник
Это было бы для всей системы , хотя, что ОП может уже сделать
Clive
что будет в масштабе всей системы? уточните пожалуйста
GoodSp33d
1
Эта семантика ( $db_url, $db_prefixкак глобальные настройки предназначена для Drupal 6. И дот-нотация работает только при использовании другой базы данных на одном сервере MySQL, а не когда (как в моем случае) вы доступ к различным серверам.
Mikl
@kantu OP спрашивает, как изменить базу данных для конкретной таблицы. Ваше первоначальное решение (до того, как вы отредактировали) внесло бы изменения в масштабе всей системы, а не на уровне таблицы.
Клайв
2
И, как я упоминал ранее, в Drupal 7 нет $db_urlглобальной $db_prefixпеременной, и даже если бы она существовала, это не решило бы проблему.
Микл