Как удалить уникальный ключ в крючке обновления


У меня есть первичный ключ и уникальный ключ в схеме моих модулей. Мне нужно удалить уникальный ключ.

Удалить индекс an просто:

function draggableviews_update_7205() {
  if (db_index_exists('draggableviews_structure', 'entity_id')) {
    db_drop_index('draggableviews_structure', 'entity_id', array('entity_id'));
  }
}

Существует функция db_index_exists(). Существует функция db_drop_unique_key() и db_add_unique_key(), но нет функции db_unique_key_exist().

Как удалить уникальный ключ в крючке обновления?

 1
Author: iStryker, 2015-02-04

2 answers

Все классы основных схем (mysql, pgsql и sqlite) проверяют наличие ограничения перед фактическим удалением, поэтому вам не нужно проверять себя. Если вы это сделаете, то на самом деле вы напрасно удваиваете объем операций с БД.

Чтобы охватить все возможные варианты, ваш код может выглядеть примерно так:

try {
  if (db_drop_unique_key($table, $name)) {
    // Constraint was found and removed.
  }
  else {
    // Constraint was not found, nothing was altered.
  }
}
catch (PDOException $e) {
  // Constraint was found, but something went wrong, see $e->getMessage() for more info.
  throw new DrupalUpdateException($e->getMessage);
}

Кстати, ограничение уникальности обрабатывается классами основных схем так же, как и индекс, поэтому db_index_exists() можно использовать и для их проверки.

 1
Author: Clive, 2015-02-04 20:29:31

Функция удаления уникального ключа заключается в db_drop_unique_key(). Вам не нужно сначала проверять, существует ли уникальный ключ, так как все классы баз данных, реализованные в Drupal, сначала проверяют, существует ли уникальный ключ.

// DatabaseSchema_mysql
public function dropUniqueKey($table, $name) {
  if (!$this->indexExists($table, $name)) {
    return FALSE;
  }

  $this->connection->query('ALTER TABLE {' . $table . '} DROP KEY `' . $name . '`');
  return TRUE;
}
// DatabaseSchema_pqsql
public function dropUniqueKey($table, $name) {
  if (!$this->constraintExists($table, $name . '_key')) {
    return FALSE;
  }

  $this->connection->query('ALTER TABLE {' . $table . '} DROP CONSTRAINT "' . $this->prefixNonTable($table, $name, 'key') . '"');
  return TRUE;
}
// DatabaseSchema_sqlite
public function dropUniqueKey($table, $name) {
  if (!$this->indexExists($table, $name)) {
    return FALSE;
  }

  $info = $this->getPrefixInfo($table);

  $this->connection->query('DROP INDEX ' . $info['schema'] . '.' . $info['table'] . '_' . $name);
  return TRUE;
}

Нет ни db_unique_key_exists(), ни db_primary_key_exists(), и они вам действительно не нужны, так как методы, используемые для их удаления, сначала проверяют, существуют ли они.

Что касается использования db_index_exists(), вы не можете использовать его для уникальных/первичных ключей, потому что он не гарантирует совместимость со всеми ядрами баз данных. Фактически, компонент database engine для PostgreSQL использует DatabaseSchema_pgsql::constraintExists() чтобы проверить, существует ли уникальный/первичный ключ.

// DatabaseSchema_pgsql
public function dropPrimaryKey($table) {
  if (!$this->constraintExists($table, 'pkey')) {
    return FALSE;
  }

  $this->connection->query('ALTER TABLE {' . $table . '} DROP CONSTRAINT ' . $this->prefixNonTable($table, 'pkey'));
  return TRUE;
} 
 1
Author: kiamlaluno, 2015-02-07 01:24:01