dbDelta не создает таблицы в WordPress

26 дек. 2012 г., 11:41:10
Просмотры: 17.1K
Голосов: 17

Я прочитал множество тем, страницу в кодексе и пробовал разные варианты, но мой код не создает таблицы. Не могу понять, где ошибка. Проверил 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');
0
Все ответы на вопрос 5
5
20

Из 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');
26 дек. 2012 г. 14:35:02
Комментарии

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

mehulved mehulved
27 дек. 2012 г. 07:21:00

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

JoeMoe1984 JoeMoe1984
8 мая 2015 г. 21:57:12

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

Jeremy Jeremy
16 окт. 2015 г. 19:19:53

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

toni_lehtimaki toni_lehtimaki
11 окт. 2017 г. 14:37:27

Ещё один важный момент: в запросе не должно быть пустых строк.

Koorosh Koorosh
28 нояб. 2024 г. 00:35:56
0

Вы можете попробовать эту функцию:

$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);
31 мар. 2016 г. 15:58:03
0

Использование 'CREATE TABLE' вместо 'create table' решило проблему в моем случае.

3 июл. 2017 г. 10:25:03
0

Помимо всех этих важных моментов, вам следует активировать хук активации.

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

25 февр. 2019 г. 10:34:55
6
-2

Ключевые слова 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, 

и так далее

8 янв. 2017 г. 15:22:39
Комментарии

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

kaiser kaiser
8 янв. 2017 г. 15:52:46

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

shirin niki shirin niki
8 янв. 2017 г. 15:56:25

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

kaiser kaiser
8 янв. 2017 г. 15:59:44

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

shirin niki shirin niki
8 янв. 2017 г. 16:13:35

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

fuxia fuxia
8 янв. 2017 г. 16:52:37

но у меня это работает: сначала я использовал верхний регистр только для create table, и мой плагин не возвращал ошибок, но таблица не создавалась. А во второй раз, когда я изменил остальные части на верхний регистр, все заработало правильно.

shirin niki shirin niki
9 янв. 2017 г. 08:42:25
Показать остальные 1 комментариев