dbDelta не создает таблицы в WordPress
Я прочитал множество тем, страницу в кодексе и пробовал разные варианты, но мой код не создает таблицы. Не могу понять, где ошибка. Проверил booking_db_version в базе - она обновляется при изменении в файле.
Вот код:
global $booking_db_version;
$booking_db_version = "1.0.0";
function booking_install() {
global $wpdb;
global $booking_db_version;
global $tableprefix;
$installed_version = get_option('booking_db_option');
$tableprefix = $wpdb->prefix . 'booking_';
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
if ( $installed_version !== $booking_db_version ) {
/* Создаем таблицу для пакетов */
$packagetable = $tableprefix . 'packages';
$sql = "create table $packagetable (
id mediumint(9) NOT NULL AUTO_INCREMENT,
name text NOT NULL,
description text NOT NULL,
city1 text NOT NULL,
city2 text NOT NULL,
PRIMARY KEY (id)
);";
dbDelta($sql);
/* Создаем таблицу для отелей */
$hoteltable = $tableprefix . 'hotels';
$sql = "create table $hoteltable (
id mediumint(9) NOT NULL AUTO_INCREMENT,
name text NOT NULL,
city text NOT NULL,
price decimal(10,2) NOT NULL,
PRIMARY KEY (id)
);";
dbDelta($sql);
/* Создаем таблицу для дополнений */
$addontable = $tableprefix . 'addons';
$sql = "create table $addontable (
id mediumint(9) NOT NULL AUTO_INCREMENT,
name text NOT NULL,
addongroup text NOT NULL,
price decimal(10,2) NOT NULL,
PRIMARY KEY (id)
);";
dbDelta($sql);
/* Создаем таблицу для групп дополнений */
$addongrouptable = $tableprefix . 'addon_groups';
$sql = "create table $addongrouptable (
id mediumint(9) NOT NULL AUTO_INCREMENT,
name text NOT NULL,
perhead text NOT NULL,
PRIMARY KEY (id)
);";
dbDelta($sql);
update_option('booking_db_version', $booking_db_version);
}
}
register_activation_hook(__FILE__, 'booking_install');

Из WordPress-codex о dbDelta:
Функция dbDelta анализирует текущую структуру таблицы, сравнивает её с желаемой структурой и при необходимости добавляет или изменяет таблицу, что делает её очень удобной для обновлений (см. wp-admin/upgrade-schema.php для большего количества примеров использования dbDelta). Однако стоит отметить, что функция dbDelta довольно привередлива. Например:
- Каждое поле в SQL-запросе должно быть на отдельной строке.
- Между словами PRIMARY KEY и определением первичного ключа должно быть два пробела.
- Необходимо использовать ключевое слово KEY вместо его синонима INDEX, и должен быть указан хотя бы один KEY.
- Нельзя использовать кавычки или обратные апострофы вокруг имен полей.
С учетом этих особенностей, вот следующие строки нашей функции, которая фактически создаст или обновит таблицу. Вам нужно будет подставить свою собственную структуру таблицы в переменную $sql.
Я изменил ваш sql: "create table $packagetable (
На этот: "CREATE TABLE " . $packagetable . " (
Вот рабочая версия вашего кода:
global $booking_db_version;
$booking_db_version = "1.0.0";
function booking_install() {
global $wpdb;
global $booking_db_version;
global $tableprefix;
$installed_version = get_option('booking_db_option');
$tableprefix = $wpdb->prefix . 'booking_';
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
if ( $installed_version !== $booking_db_version ) {
// Создание таблицы для пакетов
$packagetable = $tableprefix . 'packages';
$sql = "CREATE TABLE " . $packagetable . " (
id INT NOT NULL AUTO_INCREMENT,
name TEXT NOT NULL,
description TEXT NOT NULL,
city1 TEXT NOT NULL,
city2 TEXT NOT NULL,
PRIMARY KEY (id)
) ". $charset_collate .";";
dbDelta($sql);
// Создание таблицы для отелей
$hoteltable = $tableprefix . 'hotels';
$sql = "CREATE TABLE " . $hoteltable . " (
id mediumint(9) NOT NULL AUTO_INCREMENT,
name text NOT NULL,
city text NOT NULL,
price decimal(10,2) NOT NULL,
PRIMARY KEY (id)
) ". $charset_collate .";";
dbDelta($sql);
// Создание таблицы для дополнений
$addontable = $tableprefix . 'addons';
$sql = "CREATE TABLE " . $addontable . " (
id mediumint(9) NOT NULL AUTO_INCREMENT,
name text NOT NULL,
addongroup text NOT NULL,
price decimal(10,2) NOT NULL,
PRIMARY KEY (id)
) ". $charset_collate .";";
dbDelta($sql);
// Создание таблицы для групп дополнений
$addongrouptable = $tableprefix . 'addon_groups';
$sql = "CREATE TABLE " . $addongrouptable . " (
id mediumint(9) NOT NULL AUTO_INCREMENT,
name text NOT NULL,
perhead text NOT NULL,
PRIMARY KEY (id)
) ". $charset_collate .";";
dbDelta($sql);
update_option('booking_db_version', $booking_db_version);
}
}
register_activation_hook(__FILE__, 'booking_install');

Это сработало. Я читал, что dbDelta привередлив, но не осознавал, что отсутствие заглавных букв в CREATE TABLE
приведёт к ошибке.

Хотя WordPress не упоминает об этом на своей странице в кодексе, нельзя оставлять запятую в конце последней строки. Пример: PRIMARY KEY (id),
. dbDelta на самом деле сообщает, что создаёт таблицу, хотя этого не происходит.

Для справки: проблема с лишней запятой, PRIMARY KEY (id),
, это проблема SQL, а не dbDelta или WordPress. Поэтому и нет документации.

Обратите внимание, что при создании нескольких запросов с помощью dbDelta()
вы можете передавать SQL-запросы в виде массива в dbDelta
, вместо того чтобы вызывать dbDelta
отдельно для каждого запроса.

Вы можете попробовать эту функцию:
$table_name = "ratings";
$table_columns = "id INT(6) UNSIGNED AUTO_INCREMENT,
rate tinyint(1) NOT NULL,
ticket_id bigint(20) NOT NULL,
response_id bigint(20) NOT NULL,
created_at TIMESTAMP";
$table_keys = "PRIMARY KEY (id),
KEY ratings_rate (rate),
UNIQUE KEY ratings_response_id (response_id)";
create_table($table_name, $table_columns, $table_keys);

Помимо всех этих важных моментов, вам следует активировать хук активации.
Даже если вы разработали свой плагин и написали правильный код, вам все равно нужно повторно активировать ваш плагин, чтобы сработал хук, и ваша таблица была создана при активации плагина.

Ключевые слова SQL, такие как CREATE TABLE и UPDATE, должны быть в верхнем регистре. поэтому измените строку создания таблицы на:
"CREATE TABLE " . $packagetable . "(
и
id mediumint(9) NOT NULL AUTO_INCREMENT,
на:
id MEDIUMINT(9) NOT NULL AUTO_INCREMENT,
или это:
name text NOT NULL,
на:
name TEXT NOT NULL,
и так далее

"Ключевые слова SQL, такие как […], должны быть в верхнем регистре". Извините, но нет, это не так.

для использования функции dbDelta необходимо использовать верхний регистр. пожалуйста, проверьте эту страницу: https://codex.wordpress.org/Creating_Tables_with_Plugins

Извините, но я не вижу этого в исходном коде. Может, я что-то упустил? Возможно, вы хотите добавить в свой ответ пример мини-плагина, который покажет, что он не работает (и который кто-то сможет протестировать) с синтаксисом в нижнем регистре?

в этой ссылке: ссылка, первый абзац раздела "Создание или обновление таблицы" упоминает эту проблему.

Это верно только для CREATE TABLE
, CREATE DATABASE
, INSERT INTO
и UPDATE
. Все остальное либо не используется в регистрозависимом сравнении, либо преобразуется в нижний регистр. Ваши предложения не имеют эффекта.
