EF code first migration - Change Sql Azure table key - ef-code-first

Sql Azure does not support changing a table key. There is a work around: create a new table, transfer the data, delete the old table.
Because of this limitation, EF (4.3) is not able to migrate my model after changing a table's key.
What can I do to get EF code first to accept the new database after applying the manual work around? (Without having to drop the entire database or touch other tables)
Thanks

With a bit of manual editing you can get everything of this done inside a code based migration.
Change the key in your model (through annotations or the fluent API).
Run add-migration from the package manager console to get a new code based migration.
Exchange the generated migration steps in the migration file with the create-transfer-delete-rename method required by Azure.
Now when you run the application, the update to change keys will be done using your custom migration steps fit for Azure, rather than the default code.

Related

Is this a Flyway use case

I have delivered a Product to the customer. Now I have upgraded the Product, which includes changes to the database.
Customer wants to upgrade the Product. Now will Flyway help in the migration of Customer data from older version to newer version. Please let me know, if this is a valid use case. The flyway documentation talks about its use during development only.
Flyway allows you to change your database by running a set of scripts in a defined order. These scripts are called 'migrations' as they allow you to 'migrate' your database from one version to another.
The idea is you can start with an an empty database and each migration script will successively bring that database up from empty up to the current version. However, it's also possible to start with an existing database by creating a 'baseline' migration.
As SudhirR said, Flyway's primary use case is to define schema changes. However, it's perfectly possible to change data also. Since Flyway is just running plain SQL, in principle almost anything you can do in a SQL script you can also do in a Flyway migration.
In the case you described it should be possible to use Flyway to migrate the customer database. The steps you could take are:
Generate a sql script that includes the entire DDL (including indexes, triggers, procedures, ...) of the production database. To do this you will need to add insert statements for all the reference data present in the database.
Save this script in your Flyway project as something like 'V1__base_version.sql'
Run the flyway baseline command against your production database
This will set up your production database for use with Flyway
Add a new migration script to migrate your customer's data to the new version
e.g. create new table, copy data from old table to new table, delete old table
Run flyway migrate to upgrade production
These steps are adapted from the Flyway documentation page here.
Of course you should read the Flyway docs and manually test on a throwaway DB before you run anything against production. However I think in principle Flyway could be a good fit for your use case.
Flyway should be used for schema migrations and any reference data (basic data that is required by the system/application in order to function properly).
Putting client specific data migrations would not be a use case. However, if you can represent the data migration "generically" by not using IDs and instead use names or types than it could be a candidate. Meaning if you could write a migration in a way that could be applied to all clients, then that would be the use case to put it in as a flyway migration.
Otherwise data migrations would be applied in some other way outside of the process like requesting special access to the database or having some team that manages the database to apply the scripts.
If you are doing custom data modifications quite often then I'd say something is wrong in some other area of the SDLC and you may need to increase testing so that bugs don't mess up the data in the first place.

EntityFramwork - How do I use an existing database and apply migrations while still supporting automatic upgrade?

I have the following.
An Entity Framework model that maps against a SQLSERVER database. This has production data, but there is no __MigrationHistory table. I need to keep the data.
A new updated model including new tables, columns etc.
I would like to add migrations so that model changes can be easily managed. I would like to support both MigrateDatabaseToLatestVersion by creating all default tables, as well as being able to apply migration #2 patches on the current data structure.
I have followed Microsofts tutorial "Code First Migrations with an existing database" but this gives me the problem of the initial -ignoreChanges resulting in not being able to create the model from scratch. I need to be able to both recreate it as well as add migrations on the existing database without migration history. This since the -ignoreChanges on the initial migration gives me an empty up(), and the second migration script will only contain code for the patched tables/columns. If I don't ignore changes then the framework will try to create tables that already exist.
I was considering to not ignore changes on the initial migration and then do some kind of "CREATE TABLE IF NOT EXISTS" for all existing tables, but that seems impossible.
I bet I'm missing something right out in the open. What is it?
not tested but it should do:
use old model to create a _MigrationHistory table
copy/paste (select/insert or any etl method) the _MigrationHistory in the production database
update the model to new one
create a new migration
push the migration to the db.
DO ALL THIS FIRST IN A TEST ENVIRONMENT !

EF Core Migrations

I am trying to use migrations with a existing database and to create a new one, if not exists.
The EF Core documentations says:
If you created the initial migration when the database already exists, the database creation code is generated but it doesn't have to run because the database already matches the data model. When you deploy the app to another environment where the database doesn't exist yet, this code will run to create your database
From EFCore docs
I did initial migrations, it creates a up and down methods to create my tables. When I run it to a new database (new database name in connection string) it creates the database and tables as expected.
But if I run it to an existing database (not created by migrations), it fails at the first up method that tries to create a table that already exists, and the migrations stops to run.
Docs says "it doesn't have to run", but first thing migrations is doing is try to create an existing table.
How to prevent migrations to try to create existing tables? There is something like "create if not exists" built in on migrations? Is documentations right? It should works as expected/describe in docs?
If I'm doing it wrong, what is the strategy to work with migrations to run with existing and new on databases?
Dotnet Core version: 1.1.
EFCore version: 1.1.2.
Thanks in advance.
You need a baseline migration for the existing database. In EF 6 you used the -IgnoreChanges flag, but that doesn't exist in Core right now. See here.
You can accomplish the same thing in EF Core by commenting out all the Up() code and applying that migration. This will create the __MigrationHistory table and insert a record denoting it has been applied.
Subsequent migrations will be applied to both and if you need to create a new database you are covered.

Code First and Existing Database with Data

I'm developing a windows application which uses SQL Server Database. I have different versions of this application and they have different database structure, so I need to migrate database to the latest version on application start. I want to compare the database structure with the application model, then do alter, create or drop commands.
Also I want to use EF Code-First ORM, after some search I've figured it out that there are some useful commands and configs in code first. But the problem is, as I know, all of them drop the existing database and create a new one so the data will be lost while I need the data.
I used these lines in my application start function:
var migrator = new DbMigrator(new Configuration());
migrator.Update();
But after execution this line I will get this exception:
There is already an object named 'SomeTable' in the database.
I know that, it's right and there is that table but in structure is changed! How can I compare the structure and do the rest?
That's not how migrations work. You need a migration for every version of your database so EF can check the __MigrationHistory table and see if it has been applied. If your initializer is set to MigrateDatabaseToLatestVersion your database won't be recreated on model changes.
You could try to recreate the history: roll back to your oldest database, add a migration, add 2nd oldest version changes, create a 2nd migration, etc.
Another option is to add a migration for where you are now, generate a script (update-database -Script) then comment out the stuff that exists in each deployed database before applying it.
Yet another option would be to use the VS Schema compare utility against each database and your current database to get the changes over. Then apply a baseline migration to each (add-migration Initial -IgnoreChanges).
Now moving forward you can generate a series of migrations and your code should work as expected.

Symfony2 doctrine2 migration script into table instead of file

I am working with doctrine:migrations:diff in order to prepare database evolutions.
This command creates files into app/DoctrineMigrations
Thoses files contains sql commands in order to upgrade or downgrade database scructure.
I want to store those sql commands into the database itself. In fact, i have several instances of databases. If sql commands are store into files, it is a big problem.
I have read somewhere that DoctrineMigrations bundle can create a table called "migration_versions", but i do not manage to find where i have read this...
I cannot really understand what you're trying to do.
Migrations are used when your code needs altered database structure. For example, a new table or a new column. These new requirements for a table or column comes from your newly written code, so it's only natural to place the migrations also as a code in your repository.
How and when would migrations even get to your database? How would you guarantee that migration is executed before the code changes, which use that new structure?
Generally, migrations are used in this way:
You develop your code, add new features, change existing ones. Your code needs changes to database.
You generate doctrine migration class, which contains needed SQL statements for your current database to get to the needed state.
You alter the class adding any more required SQL statements. For example, UPDATE statements to migrate your data, not only the structure.
You execute migration locally.
You test your code with database changes. If you need more changes, you either add new migration, or execute migration down, delete it and regenerate it. Never change the migration class, as you'll loose what's supposed to be in the database and what's not.
You commit your migration together with code that uses it.
Then comes the deployment part:
- For each server, upload the code, clear and warm-up cache, run other installation scripts. Then run migrations. And only then switch to the new code.
This way your database is always in-sync with current code in the server that uses that database.
migration_versions database table is created automatically by doctrine migrations. It holds only the version numbers of migration classes - it's used for keeping track which migrations were already run and which was not.
This way when you run doctrine:migrations:migrate all not-yet-ran migrations are executed. This allows to migrate few commits at once, have several migrations in a commit etc.

Resources