Задать вопрос

Как изменить AUTO_INCREMENT в таблице, связанной с другой?

Я пишу конвертор для конвертирования записей из старой БД в новую с использованием Symfony и A2lixI18nDoctrineBundle

В старой БД в одной таблице хранились названия на двух языках. Теперь будет использоваться одна таблица для хранения дерева категорий и вторая таблица для названий категорий на двух языках. Проблема в следующем: мне нужно вставлять в БД с помощью Doctrine элементы с уже установленными ID. Это я решил с помощью следующего кода:
$classMetadata = $this->getClassMetadata($entity);
$classMetadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE);
$classMetadata->setIdGenerator(new AssignedGenerator());

Таким образом я могу сейчас устанавливать свои айдишки. Но после этого мне нужно чтобы новые категории добавлялись с генерацией новых ID, которые не должны пересекаться с существующими. Я не очень хочу самостоятельно для всех моделей генерировать ID как минимум из-за того, что будут лишние запросы к БД. Их будет не много, но, по-хорошему, их стоило бы не делать. Так вот, когда у меня была лишь одна таблица и с ней ничего связано не было (таблица локализированных записей) я делал следующее:
1. Таблица для категорий генерировалась изначально с AUTO_INCREMENT
2. Перед тем, как начать конвертирование категорий я убирал из таблицы AUTO_INCREMENT и вышеуказанным кодом изменял стратегию генерации ID для этой модели.
3. Конвертировал записи, добавлял их в таблицу
4. После конвертации категорий я создавал новую таблицу со структурой таблицы категорий (1), добавлял AUTO_INCREMENT для ID (2), устанавливал значение AUTO_INCREMENT для новой таблицы значение {MAX_CATEGORY_ID + 1} (3), переносил конвертированные записи со старой таблицы в новую (4), удалял прежнюю таблицу (5), переименовывал новую таблицу в старую.
private function setAutoincrementValue($entity, $autoincrement)
{
    $tableName = $this->getClassMetadata($entity)->getTableName();
    $tableNameNew = $tableName.'_new';

    $this->getEntityManager()->getConnection()
        ->exec(
            "DROP TABLE IF EXISTS `{$tableNameNew}`;
            CREATE TABLE `{$tableNameNew}` LIKE `{$tableName}`;
            ALTER TABLE `{$tableNameNew}` CHANGE COLUMN `id` `id` INT(11) NOT NULL AUTO_INCREMENT;
            ALTER TABLE `{$tableNameNew}` AUTO_INCREMENT = {$autoincrement};
            INSERT INTO `{$tableNameNew}` SELECT * FROM {$tableName};
            DROP TABLE `{$tableName}`;
            RENAME TABLE `{$tableNameNew}` TO `{$tableName}`;"
        );
}

Это решение работало пока я не добавил локализацию для категорий и не вынес ее в отдельную таблицу.

Я пробовал сперва установить AUTO_INCREMENT в значение, которое превышает max(ID) категорий и установить стратегию генерации ID в доктрине на ручную (при этом в таблице был установлен AUTO_INCREMENT для ключа), но тогда вылетала ошибка здесь.

Если же установать значение AUTO_INCREMENT, но не изменять стратегию генерации ID, то все значения вставятся с ID, которое превышает устанавливаемое значение AUTO_INCREMENT

Я предполагаю, что эта проблема вылезла бы и потом - когда я начну добавлять контент к категориям - он будет привязан к категориям и будут использоваться ключи для связи.

Теперь собираю все вместе и формирую результирующий вопрос: каким путем идти чтобы можно было корректно вставлять записи в таблицу с предустановленными ключами и записями в связанную таблицу внешним ключом и в последствии иметь возможность пользоваться AUTO_INCREMENT для первичного ключа таблицы?

Возможно, я что-то не так сформировал - в комментариях отвечу на вопросы.

UPDATE
на сколько я понимаю, то более чистым и правильным решением будет создание собственного ID-генератора (который будет генерировать ID как {max(id_on_table) + 1} если у сущности не установлен ID и возвращать ID сужности, если установлен) и использовать его для конвертируемых моделей
  • Вопрос задан
  • 1229 просмотров
Подписаться 2 Оценить Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы