Swift Vapor: удалите поле базы данных с помощью миграции и из структуры одновременно

#swift #database-migration #vapor

Вопрос:

Я добавил миграцию базы данных, чтобы удалить поле:

 static func prepare(on conn: PostgreSQLConnection) -> EventLoopFuture<Void> {
    return Database.update(User.self, on: conn) { builder in
        builder.deleteField(for: .name)
    }
}
 

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

Мне это не кажется хорошей практикой, и я, вероятно, делаю здесь что-то не так.
Что я могу сделать вместо этого?

Ответ №1:

Что вы можете сделать, так это получить поле по имени и удалить его:

 builder.deleteField(User.Database.QueryField.column("users", "name"))
 

где

  • users является ли имя таблицы
  • name является ли имя столбца/поля

Ответ №2:

Это полная миграция, показывающая добавленное поле, а затем возврат, чтобы удалить его:

     struct UpdateUserTable1: Migration {
        func prepare(on database: Database) -> EventLoopFuture<Void> {
            database.schema("User")
                .field("nextAttemptAt", .datetime)
                .update()
        }

        func revert(on database: Database) -> EventLoopFuture<Void> {
            database.schema("User")
                .deleteField("nextAttemptAt")
                .update()
        }
    }
 

Как вы можете видеть, миграция не требует, чтобы поле было определено в модели или нет на любом этапе. Это правильный способ сделать это с помощью Fluent.