Проблемы в журнале изменений миграции базы данных Grails

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

1.) Сначала я создаю пустой журнал изменений. Прежде чем запускать эту команду, я установил для своей разработки dbCreate значение create.

grails dbm-create-changelog

2.) Затем я создаю первоначальный список изменений gorm. В учебнике говорится, что я должен использовать флаг prod, но, поскольку моя производственная база данных пуста, я опускаю флаг prod. Прежде чем запускать эту команду, я закомментировал настройку dbCreate для разработки.

grails dbm-generate-gorm-changelog --add changelog-1.0.groovy

На данный момент моя папка migrations содержит файлы changelog.groovy и changelog-1.0.groovy. Я буду называть changelog-1.0.groovy как changelog #1

3.) Теперь я пытаюсь инициализировать свою производственную базу данных с помощью только что созданного журнала изменений. Я установил миграцию базы данных updateOnStart и updateOnStartFileNames в своей конфигурации, как указано в руководстве, на которое я ссылался. Моя производственная база данных существует, но пуста (нет таблиц). Параметр dbCreate для моей производственной среды закомментирован.

grails prod run-app

ПРОБЛЕМА:

На первый взгляд кажется, что это сработало, но когда я запускаю grails prod dbm-gorm-diff и генерирую changelog #2, я вижу изменения, которых не должно быть. Я также вижу, что наборы изменений являются законными по сравнению с текущим состоянием рабочей базы данных. Это означает, что производственная база данных была неправильно инициализирована с помощью changelog #1. Никаких изменений быть не должно, так как я ничего не менял. Я пробежал grails prod dbm-gorm-diff сразу после того, как пробежал grails prod run-app.

В файле changelog #2 есть пять наборов изменений. Я проверил, что все эти наборы изменений представлены в файле changelog #1. Первые четыре набора изменений в changelog #2 имеют unique: "true". Эти четыре набора изменений также являются единственными наборами изменений, которые содержат unique: "true" в changelog #1. Я все еще не могу объяснить, почему существует пятый набор изменений. Я не вижу в этом ничего примечательного, хотя это для таблицы user_role, используемой Spring. Плагин безопасности. Вот changelog #2:

databaseChangeLog = {

    changeSet(author: "typoknig (generated)", id: "1341970550063-1") {
        createIndex(indexName: "authority_unique_1341970549765", tableName: "role", unique: "true") { // This table is for the Spring Security plugin's "Role" domain class.
            column(name: "authority")
        }
    }

    changeSet(author: "typoknig (generated)", id: "1341970550063-2") {
        createIndex(indexName: "name_unique_1341970549772", tableName: "foo", unique: "true") { // This is just a table for one of my domain classes that happens to have a field with a unique constraint.
            column(name: "path")
        }
    }

    changeSet(author: "typoknig (generated)", id: "1341970550063-3") {
        createIndex(indexName: "name_unique_1341970549774", tableName: "bar", unique: "true") { // This is just a table for one of my domain classes that happens to have a field with a unique constraint.
            column(name: "name")
        }
    }

    changeSet(author: "typoknig (generated)", id: "1341970550063-4") {
        createIndex(indexName: "username_unique_1341970549777", tableName: "user", unique: "true") { // This table is for the Spring Security plugin's "User" domain class.
            column(name: "username")
        }
    }

    changeSet(author: "typoknig (generated)", id: "1341970550063-5") {
        createIndex(indexName: "FK143BF46A5FBC0B79", tableName: "user_role") { // This table is for the Spring Security plugin's "UserRole" domain class.
            column(name: "role_id")
        }
    }
}

Что мне нужно сделать, чтобы убедиться, что моя производственная база данных инициализирована правильно?

ОБНОВЛЕНИЕ №1:

Не знаю почему, но createIndex не работает с unique: "true". Для первых четырех наборов изменений я просто переместил unique: "true" в место, где рассматриваемый столбец изначально создавался в changeset #1. Остается только пятый набор изменений в changelog #2. Я по-прежнему не вижу проблем с набором изменений, поэтому не понимаю, почему он не применяется.

ОБНОВЛЕНИЕ №2:

Я обнаружил, что могу переместить все вызовы createIndex из отдельных наборов изменений в соответствующий набор изменений, в котором была создана таблица (которой принадлежит индекс). Похоже, это решило все мои проблемы. Если кто-то не сможет предоставить убедительную причину не делать этого, я думаю, что сделаю это частью моего рабочего процесса по созданию журнала изменений. Например, эти наборы изменений:

changeSet(author: "typoknig (generated)", id: "1342037835503-31") {
    createTable(tableName: "user_role") {
        column(name: "role_id", type: "bigint") {
            constraints(nullable: "false")
        }

        column(name: "user_id", type: "bigint") {
            constraints(nullable: "false")
        }
    }
}

changeSet(author: "typoknig (generated)", id: "1342037835503-103") {
    createIndex(indexName: "FK143BF46A4E6CF59", tableName: "user_role") {
        column(name: "user_id")
    }
}

changeSet(author: "typoknig (generated)", id: "1342037835503-104") {
    createIndex(indexName: "FK143BF46A5FBC0B79", tableName: "user_role") {
        column(name: "role_id")
    }
}

Был бы этот набор изменений:

changeSet(author: "typoknig (generated)", id: "1342037835503-31") {
    createTable(tableName: "user_role") {
        column(name: "role_id", type: "bigint") {
            constraints(nullable: "false")
        }

        column(name: "user_id", type: "bigint") {
            constraints(nullable: "false")
        }
    }
    createIndex(indexName: "FK143BF46A5FBC0B79", tableName: "user_role") {
        column(name: "role_id")
    }
    createIndex(indexName: "FK143BF46A4E6CF59", tableName: "user_role") {
        column(name: "user_id")
    }
}

person ubiquibacon    schedule 11.07.2012    source источник
comment
Пробовали ли вы не полагаться на функциональность updateOnStart, а вместо этого запускать сценарий обновления напрямую?   -  person cdeszaq    schedule 11.07.2012
comment
Вы почти всегда будете получать изменения при запуске diff. Diff несовершенен, и его следует использовать в качестве предложения. Я всегда получаю наборы изменений createIndex, когда делаю diff. Я просто удаляю их и сохраняю/настраиваю то, что мне нужно.   -  person Gregg    schedule 11.07.2012
comment
@Gregg Если бы diff показал мне изменения, которые уже были применены к моей БД, я был бы раздражен, но не очень обеспокоен. Однако это не так. Разница точна, потому что changelog #1 не был правильно применен к моей производственной БД. Производственная БД была инициализирована из журнала изменений, созданного из БД разработки, поэтому даже если есть различия, БД должны быть идентичными. Опять же, это не так. Например, что касается первого набора изменений в changelog #2, БД разработки имеет ограничение unique для столбца authority в таблице role, а производственная БД — нет.   -  person ubiquibacon    schedule 11.07.2012
comment
@cdeszaq Я еще не пробовал. Я попробую и отчитаюсь.   -  person ubiquibacon    schedule 11.07.2012
comment
@Gregg - Я тоже так делаю. Как для обнаружения вещей, которые diff пропустил или не может сделать с помощью встроенных операций, так и для того, чтобы просто очистить изменения, чтобы они не были такими подробными.   -  person cdeszaq    schedule 11.07.2012
comment
@cdeszaq Я пытался запустить dbm-update в своей производственной БД, но, видимо, эта команда не будет работать, если ваша база данных пуста (нет таблиц). Я хотел бы перейти от пустого к текущему состоянию GORM, как это предлагается сделать в учебнике.   -  person ubiquibacon    schedule 12.07.2012


Ответы (1)


Наборы изменений могут зависеть от целевой базы данных. Например, сайт grails.org, использовавший таблицы MyISAM с MySQL и dbm-gorm-diff, всегда добавлял несколько createIndex наборов изменений, даже если они были определены в предыдущих наборах изменений.

Я действительно не понимаю, как перемещение объявлений createIndex в наборы изменений createTable может что-то изменить. Можете ли вы уточнить, как это устранило все ваши проблемы?

person Peter Ledbrook    schedule 10.09.2012
comment
Питер, я не понимаю, как перемещение объявлений createIndex в наборы изменений createTable тоже изменит ситуацию, но это так. Я не могу объяснить, почему это работает, хотя и хотел бы. - person ubiquibacon; 11.09.2012