Всем привет!
В таблице одно из полей является первичным ключом. В одном из модулей Drupal, который использует эту таблицу, при добавлении новой записи через функцию drupal_write_record() возникает нарушение уникальности поля.
Таблицу через phpMyAdmin я посмотрел, видимых нарушений в ней нет. Все записи присутствуют.
Лог ошибок показывает, что при вызове функции drupal_write_record() в ключевое поле пытаются записаться различные значения, возрастающие при каждой попытке. Но в таблице, для определенности, 90 записей, то есть ближайшее свободное значение для ключа - это 91. А функция при первом вызове подставила значение 7 (это было видно в логе), следующая попытка увеличила это значение и т.д.
Где в моей базе данных закрался косяк? От куда функция drupal_write_record() берёт значения для уникальных полей?
Где функция drupal_write_record() берёт значения для уникальных индексных полей?
Главные вкладки
Лучший ответ
Ура! Разобрался в логике работы модуля. Модуль, кстати, называется Domain Access.
Есть еще таблица связанная с модулем - domain_export. В ней было всего 5 записей. Состоит она из двух полей. Одно из полей, с именем "domain_id", как раз и является авто-инкрементным.
Добавил в эту таблицу строку с данными из последней записи таблицы domain и всё: добавление новых записей через интерфейс модуля стал возможен. Значит кто-то ранее вносил изменения в эту таблицу.
Комментарии
Функция drupal_write_record() ниоткуда не берет эти значения.
ID либо передаётся при её вызове, либо в ID передаётся NULL и СУБД при вставке назначает очередной инкремент.
У вас в таблице может вообще не быть строк, а очередной инкремент будет 1 000 000.
Нужно для начала проверить, что передаётся в drupal_write_record().
Для саморазвития:
SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'DatabaseName' AND TABLE_NAME = 'TableName';
Инкремент уникального ключа делает автоматически, если записи стерты инкремент не уменьшается.
Уважаемый камрад.
Посмотрел, в таблице данное поле не автокриментно. Но уникально. Значит сам модуль отвечает за корректность значений в этом поле?
см. https://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_...
При создании если поле 'type' => 'serial' то автоинкрементно
Уважаемый камрад.
Спасибо за ответ. Функции max() и count() я изучил. Запросы SQL касался поверхностно.
Запросы к БД сделаю. Посмотрю что выйдет.
Запрос показал значение Null. То есть, автокремента нет.
Значит сам модуль генерирует новое значение для ключевого поля, так?
А разработчик модуля написал, что это значение автоматические генерируется из drupal_write_record(). Вот его ответ:
It is auto-generated from drupal_write_record(). I don't recall how that code looks up the value to use.
Скажите, куда мне дальше копать?
Сначала надо разобраться в причинах такого поведения модуля.
Откуда взялись материалы с ID, большим чем текущее значение счетчика автоинкремента.
Я почему-то сомневаюсь, что поле ID уникально, но не автоинкрементно.
Если конечно по логике приложения нет необходимости назначать ID материала не по возрастающему порядку.
Уважаемый камрад.
Я посмотрел структуру таблицы. Поле ID является уникальным, но без автоинкремента. Также оно является первичным ключом. Это 100%. Для точности: поле называется не ID, но не думаю что это важно.
Через интерфейс модуля успешно добавляли новые записи пару лет назад. За прошедшее время успели обновить ядро drupal. Но всё это я не застал.
Модуль обновил до последней рабочей версии.
Я так понимаю, что придется капать в коде модуля и смотреть что от куда берется?
А если я попробую изменить структуры таблицы и задать для поля свойство автоинкримента? СУБД даст это сделать при наличии записей в таблице. Где и что мне внести в этом случае, чтобы для автоинкримента бралось нужное значение. Например, я знаю сколько записей в таблице и смогу указать нужное значение.
Это "сейчас" так, есть гарантия что параметры таблиц в БД никто не менял?
А если всё-таки не менял, значит назначение ID новому материалу производится "программно" в каком-то модуле, скорее всего "самописном".
Значит надо сначала выяснить, каким образом новому материалу назначается ID: программно или автоинкрементом в БД.
Если "программно" нужно искать ошибку в коде.
Если автоинкрементом - установить автоинкремент для поля ID и увеличить счетчик автоинкремента для этой таблицы .
Если решитесь разобраться сами, не забудьте обязательно сделать бэкап базы данных.
Ура! Разобрался в логике работы модуля. Модуль, кстати, называется Domain Access.
Есть еще таблица связанная с модулем - domain_export. В ней было всего 5 записей. Состоит она из двух полей. Одно из полей, с именем "domain_id", как раз и является авто-инкрементным.
Добавил в эту таблицу строку с данными из последней записи таблицы domain и всё: добавление новых записей через интерфейс модуля стал возможен. Значит кто-то ранее вносил изменения в эту таблицу.