Migraciones de bases de datos en Swift (iOS/macOS): reseña de herramientas y ejemplos
Las migraciones de bases de datos son el proceso de cambio controlado del esquema de datos (tablas, índices, relaciones) sin perder la información ya existente. En el ecosistema Swift para las plataformas de Apple (iOS, macOS, watchOS, tvOS), los desarrolladores utilizan varios enfoques: desde el integrado Core Data hasta bibliotecas de terceros como GRDB.swift y Fluent. En este artículo, analizaremos las herramientas clave, sus capacidades y proporcionaremos ejemplos prácticos de código.
1. Core Data y migraciones (ligeras y manuales)
Core Data es el framework estándar de Apple para trabajar con el modelo de objetos. Las migraciones se dividen en dos tipos:
- Migración ligera (Lightweight Migration) — automática, si los cambios no implican transformaciones complejas (agregar atributos, eliminar, renombrar con mapping model).
- Migración manual (Manual Migration) — se requiere cuando es necesario cambiar tipos de datos, fusionar entidades o realizar transformaciones personalizadas.
Ejemplo de configuración de migración ligera en Swift:
import CoreData
lazy var persistentContainer: NSPersistentContainer = { let container = NSPersistentContainer(name: "MyDataModel") let description = container.persistentStoreDescriptions.first description?.shouldMigrateStoreAutomatically = true description?.shouldInferMappingModelAutomatically = true container.loadPersistentStores { _, error in if let error = error { fatalError("Error al cargar Core Data: \\(error)") } } return container}()2. GRDB.swift — biblioteca moderna para SQLite con migraciones
GRDB.swift es una potente biblioteca para trabajar con SQLite que ofrece un mecanismo de migraciones integrado. Permite versionar el esquema de la base de datos y ejecutar cambios de forma secuencial.
Instalación a través de Swift Package Manager:
// Package.swiftdependencies: [ .package(url: "https://github.com/groue/GRDB.swift.git", from: "6.0.0")]Ejemplo de migración con GRDB.swift:
import GRDB
var migrator = DatabaseMigrator()
// Migración 1: creación de tablamigrator.registerMigration("v1_create_users") { db in try db.create(table: "users") { t in t.autoIncrementedPrimaryKey("id") t.column("name", .text).notNull() t.column("email", .text).unique() }}
// Migración 2: agregar columnamigrator.registerMigration("v2_add_age") { db in try db.alter(table: "users") { t in t.add(column: "age", .integer).defaults(to: 0) }}
// Aplicar migraciones al iniciar la aplicaciónlet dbQueue = try DatabaseQueue(path: "/path/to/database.sqlite")try migrator.migrate(dbQueue)3. Fluent (Vapor) — ORM para Swift del lado del servidor
Fluent es un ORM que forma parte del framework Vapor (Swift del lado del servidor para macOS). Las migraciones en Fluent se describen como clases que implementan el protocolo Migration.
Ejemplo de migración para Fluent 4:
import Fluent
struct CreateUser: Migration { func prepare(on database: Database) -> EventLoopFuture<Void> { database.schema("users") .id() .field("name", .string, .required) .field("email", .string, .required).unique(on: "email") .create() } func revert(on database: Database) -> EventLoopFuture<Void> { database.schema("users").delete() }}
// Registro en configure.swiftapp.migrations.add(CreateUser())try app.autoMigrate().wait()4. Comparación de herramientas
- Core Data — adecuado para aplicaciones Apple con vinculación al modelo de objetos. Las migraciones suelen ser automáticas, pero los escenarios complejos requieren mappin