¿Qué herramienta utilizar para las migraciones de bases de datos de SQL Server y por qué a partir de 2017?

Quiero saber una herramienta para usar para las migraciones de la base de datos de SQL Server y por qué a partir de 2017, ya que me preocupa este tema, para poder automatizar este proceso tanto como sea posible.

¿Qué opinas sobre las migraciones de Entity Framework Code First, suponiendo que estoy usando .Net?

Respuestas (3)

Hay dos productos principales que conozco en el campo relativamente nuevo de la migración de bases de datos.

ruta migratoria

Flyway es básicamente una herramienta para organizar, rastrear y aplicar automáticamente una colección de scripts SQL que escribe.

Se puede usar desde la aplicación Java y desde la línea de comandos para entornos que no sean Java.

Libre de costo. Fuente abierta.

Liquibase

Liquibase es un competidor de Flyway y tiene el mismo propósito.

Flyway es bueno, pero no genera los scripts de migración, mientras que Entity Framework Code First Migrations sí lo hace.
@MiguelDomingos No hay herramientas de diferencias que yo sepa que puedan hacer un trabajo perfecto al 100% de escribir scripts para recrear la totalidad de una base de datos compleja. El único enfoque perfecto es escribir toda la creación y modificación de su base de datos en secuencias de comandos SQL que luego recopila y aplica a través de una herramienta como Flyway exclusivamente.
.@BasilBourque Entity Framework puede andamiar todas las migraciones con precisión porque hay un modelo hecho de clases en C# y ese modelo se mantiene sincronizado con la base de datos. Dado que Flyway no sabe nada acerca de las clases de aplicaciones, con Flyway debe escribir sus propios scripts de migración desde cero.
@MiguelDomingos Hay más en una base de datos que las tablas de entidades. Pero buena suerte para ti.
.@BasilBourque Las tablas de entidades son una parte importante de una base de datos y al menos es mejor generar eso que nada.
Usando EF Core, es posible crear migraciones personalizadas, usando alguna API fluida o SQL simple de eventos. También puede generar un script para la migración. En mi proyecto, el script se genera y confirma como parte del proceso de desarrollo, luego se usa en una canalización de CI/CD para actualizar automáticamente la base de datos. De esta manera, tiene el beneficio de las migraciones generadas automáticamente (la mayoría de las veces), la capacidad de escribir su propia migración de sql y el beneficio de verificar el script en la revisión de la solicitud de extracción.

En nuestro proyecto (aplicación dotnet core alojada en Azure) usamos EF Core para administrar las migraciones de base de datos.
La configuración se ve así:

  1. Hay un proyecto C# separado con entidades (modelos EF Code First).
  2. Hay un proyecto de C# separado con Repositorios (código relacionado con EF Core), que también contiene migraciones (no tenemos toneladas de estas). Se llama Infraestructura.AzureSql
  3. En el proyecto Infrastructure.AzureSql tenemos un archivo README.md con sugerencias:
To add migration:

1. Open Visual Studio Package Manager Console
2. Add-Migration <migration-name> -Verbose -Project src\Infrastructure.AzureSql -StartupProject src\SampleProject

To generate sql script:
 1. Open Visual Studio Package Manager Console
 2. Script-Migration -Verbose -Idempotent -Output "deploy\sql\SampleDB.sql" -Project src\Infrastructure.AzureSql -StartupProject src\SampleProject

Y el proceso de realizar el cambio en el esquema de base de datos se ve de la siguiente manera:

  1. Realice el cambio en el modelo Code First, por ejemplo, agregue nuevos campos
  2. Modifique el contexto de datos agregando la configuración necesaria a la clase DataContext :
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Product>(builder =>
    {
        builder.ToTable("Product");
        // Configuring new property
        builder.builder.Property(product => product.Сategory).HasColumnType("nvarchar(32)");
        builder.HasIndex(product => product.Category);
    }
}
  1. Agregar nueva migración usando el Add-Migrationcomando:
    El comando creará un nuevo archivo de migración con el nombre que contiene el nombre de la migración: 20210323165355_Product-Add-Category.cs. Detectará automáticamente los cambios en el modelo e incluirá las declaraciones correspondientes en el archivo, por ejemplomigrationBuilder.AddColumn<string>(name: "Category", table: "Product", type: "nvarchar(32)", nullable: true);
Add-Migration Product-Add-Category -Verbose -Project src\Infrastructure.AzureSql -StartupProject src\SampleProject
  1. Cuando sea necesario, los pasos personalizados se pueden agregar manualmente al archivo de migración, 20210323165355_Product-Add-Category.csya sea mediante la API fluida de MigrationBuilder predefinida o mediante el uso de SQL personalizado migrationBuilder.Sql(fillInProductCategoryScript);; simplemente agregue el código junto con uno generado automáticamente.
    Advertencia: EF Core mantiene el esquema de base de datos actual descrito a través de la API fluida en el archivo llamado <DbContextName>ModelSnapshot.cs. Si se realiza algún cambio manual en el esquema a través de SQL, debe reflejarse en la instantánea (y también en el archivo 20210323165355_Product-Add-Category.Designer.csque representa la instantánea del esquema después de aplicar la migración). Normalmente confiamos en los cambios de esquema generados automáticamente y solo agregamos scripts de transformación de datos personalizados a través de SQL.
  2. Cuando se completa la lógica de migración, es necesario volver a generar el script. Nuevamente, no tenemos demasiados cambios, por lo que estamos usando el mismo archivo para todas las migraciones.
Script-Migration -Verbose -Idempotent -Output "deploy\sql\SampleDB.sql" -Project src\Infrastructure.AzureSql -StartupProject src\SampleProject

El comando vuelve a generar el script de migración en función de las migraciones que rodean los cambios con declaraciones condicionales:

IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20210323165355_Product-Add-Category')
BEGIN
    ALTER TABLE [Product] ADD [Category] nvarchar(32) NULL;
END;

IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20210323165355_Product-Add-Category')
BEGIN
    CREATE INDEX [IX_Product_Category] ON [Product] ([Category]);
END;

IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20210323165355_Product-Add-Category')
BEGIN
    INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
    VALUES (N'20210323165355_Product-Add-Category', N'3.1.3');
END;

GO
  1. Todos los cambios se confirman (incluido el script SQL de migración), por lo que el SQL generado se puede verificar durante la revisión del código.
  2. La canalización de CI/CD contiene los comandos para aplicar el script de migración. Es idempotente, por lo que es seguro aplicarlo en cada despliegue. Si el script de migración contiene declaraciones muy pesadas y queremos tener más control sobre el proceso (y su tiempo), podemos ejecutar el mismo script manualmente. Como es idempotente, la próxima implementación omitirá las partes que se completaron anteriormente.

Yo revisaría dbatools.io

Tienen scripts de PowerShell que pueden hacer exactamente lo que necesitas. Y es gratis.

¿Alguna actualización / comentario sobre mi respuesta?