Flyway: non-empty schema without metadata table - flyway

Found non-empty schema "public" without metadata table! Use init() or set initOnMigrate to true to initialize the metadata table.
I'm using Postgres 9.2 with Postgis 2.0. This means that by default when I create a new database there will be a table created in public schema called spatial_ref_sys.
When I run flyway migrate on this database, I get the above error. Running init seems to create the public.schema_version table and mark version 1 as SUCCEDED without actually running the the migration file. I've also tried combinations of initOnMigrate with no success. Flyway is not configured to manage any schemas.
Any ideas on how I can run a migration in this scenario?

The title is somewhat contradictory, as the database is indeed not virgin as you installed, through the PostGIS extension, a number of objects in the public schema.
You can either
set flyway.schemas to a new schema, say my_app, which will then be created automatically by Flyway. Your application should then use this one instead of public (recommended)
set flyway.baselineOnMigrate to true or invoke flyway.baseline() against the public schema. This will work, but public will then contain a mix of both your application objects and the PostGIS objects

If you are using Gradle you can run
./gradlew -Dflyway.schemas=public flywayClean flywayMigrate
Where public is the name of the database containing the schema_versions table. That should delete the table and metadata as well as running the migrations to get it back up to date.
Caution!
This will delete all data in public schema

I think this error comes only with latest version of Flyway i.e. above 4.03. I didn't received in the earlier project but got it when I am using Flyway version 5.07 in my latest project. Putting the code here that resolve my issues
public class FlywayConfig {
#Autowired
DataSource dataSource;
#Autowired
Config config;
#Bean
public Flyway flyway(){
Flyway flyway = new Flyway();
flyway.setDataSource(dataSource);
flyway.setSqlMigrationPrefix("V");
flyway.setLocations(new String[] { config.getSqlLocation() });
flyway.setBaselineOnMigrate(true);
// *******************flyway.clean(); ********************// this will wipe out the DB, be careful
flyway.migrate();
return flyway;
}
}

this work for me , i were figthin with the same problema a lot of time
my project was building on maven
Flyway flyway = new Flyway();
flyway.setDataSource(dataSource);
flyway.setLocations("db/your_db");
flyway.setTable("name_of_schema");
next a added this line
flyway.setBaselineOnMigrate(true);
flyway.clean();
next this lines
MigrationInfo migrationInfo = flyway.info().current();
flyway.migrate();
and i let you the URL of my references from flyway.org
Flyway.org/documentation/commandline/baseline

In my case the problem started when I deleted all the rows in the table myschema.schema_version
./gradlew flywayInit did the trick and the error is not showed anymore.

Related

Asp.Net Two Local DBContexts to One Azure DBContext

I have a web app that I developed through this tutorial:
https://learn.microsoft.com/en-us/aspnet/web-forms/overview/getting-started/getting-started-with-aspnet-45-web-forms/introduction-and-overview
This tutorial put two DBContext (ApplicationDbContext and MyDBContext) with their respective databases with EF and Code First, I published in Azure several months ago and everything works well, both locally and in Azure. From the beginning I noticed that Azure only manages a database. In this database Azure are all the tables of the two DBContexts and as I said everything works well. I have done dozens of Migrations, only in my own WebApp tables (MyDBContext)
Now I want to add fields to a table of the AplicationDBContext, specifically to the AspNetUser table, so I modify the following code
public class ApplicationUser: IdentityUser
{
/// My New Field
public bool Disabled {get; set; }
public ClaimsIdentity GenerateUserIdentity (ApplicationUserManager manager)
{
var userIdentity = manager.CreateIdentity (this, DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
public Task <ClaimsIdentity> GenerateUserIdentityAsync (ApplicationUserManager manager)
{
return Task.FromResult (GenerateUserIdentity (manager));
}
}
Then I implemented:
Enabled-Migrations -ContextTypeName ApplicationDbContext -MigrationsDirectory Migrations \ ApplicationDbContext
Add-Migration -ConfigurationTypeName MyWebApp.Migrations.ApplicationDbContext.Configuration "AddFldAspNetUsers"
Update-Database -ConfigurationTypeName MyWebApp.Migrations.ApplicationDbContext.Configuration
Locally everything works fine, but when I publish in Azure I get the following error:
Server Error in '/' Application.
The model backing the 'ApplicationDbContext' context has changed since the database was created. Consider using Code First Migrations to update the database
I do not know how to solve it, I need help:
I have faced the same problem recently. The reason behind the problem you have scaffold the migration but haven't updated the Identity database tables in Azure.
Please follow the below points
Before publishing, in publish window go to settings, there you could
find ApplicationDbContext under Databases section.
Give a tick to the check box Execute code first migrations(runs on
application start) option. Try to re-publish it again. :)

EntityFrameworkCore for Sqlite not creating __EFMigrationHistory table

Before I explain my issue, I have some experience with entity framework 5 and 6 code first migrations, running add-migration/update-database and a few more specific commands from the Package Manager console. All of the migration history was handled out of the box in the __MigrationHistory table.
I am now writing a UWP app and using EntityFrameworkCore sqlite. The app is set up to scaffold new migrations and does so correctly.
When applying migrations the app needs to automatically deduce, on install and first startup, if the database exists, and the current database migration version. It can then apply the relevant migration procedures, including creating the database if required.
Currently, I attempt to perform the migrations in my DbContext on startup:
public class MyContext : DbContext
{
public DbSet<SomeEntity> MyEntities { get; set; }
static MyContext()
{
using(var db = new MyContext())
{
db.Database.Migrate();
}
}
This works perfectly for a new app on first startup. On second startup however, or after the addition of a new migration, the Migrate() method fails as the tables it is attempting to create already exist.
SQLite Error 1: 'table \"MyEntities\" already exists'
This error comes from rerunning the migration that has been previously applied. The database itself needs to be aware of it's migration history as was previously handled with __EFMigrationHistory. Currently this table is not being created for me.
I am suspecting that I need to manually build a solution to this, maybe creating my own __MigrationHistory table and keeping it up to date, as per this post here
I wondered what solutions people have used for this issue, or if there is anything out of the box that I'm being silly and missing.
Let me know if more detail needed.
I solved this in a manner of speaking but I'm still not sure why the __MigrationHistory table was not automatically generated...
I couldn't find any evidence of other people struggling with this issue in UWP apps, so it is likely project specific and something caused by how the solution was set up.
Anyway, the changes I made:
I created a MigrationHistory model and added it as a DbSet to my DbContext.
Model
namespace MyApp.Shared.Models.Infrastructure
{
public class MigrationHistory
{
public string MigrationId { get; set; }
public string ProductVersion { get; set; }
}
}
DbContext additions
public class MyContext : DbContext
{
public DbSet<MigrationHistory> __MigrationHistory { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
#region Primary Keys
modelBuilder.Entity<MigrationHistory>().HasKey(mh => mh.MigrationId);
At this stage, on running add-migration entity framework attempted to create the __MigrationHistory table. This would result in an error if I ran my application, as applying the migration would result in the error:
SQLite Error 1: 'table \"__MigrationHistory\" already exists'
So I added the following code to my MyContextModelSnapshot class
modelBuilder.Entity("MyApp.Shared.Models.Infrastructure.MigrationHistory", b =>
{
b.Property<string>("MigrationId")
.ValueGeneratedOnAdd();
b.Property<string>("ProductVersion");
b.HasKey("MigrationId");
b.ToTable("__MigrationHistory");
});
Once it is in the snapshot, it can stay there, and it acts to prevent entity framework attempting to add this table in future migrations.
On startup my app now runs
using (var db = new Assessment.Data.WindowsUniversal.AssessmentContext())
{
db.MigrateDatabase();
}
And it works perfectly, consulting the table and applying migrations where necessary.
I feel like this is a solution to a problem that doesn't really exist, and that is of my own making, but I'll leave this here in case it's relevant to somebody else.
As far as i've come up with while having your same issue, i found out the debug database (inside your \bin\Debug folder) won't have the __EFMigrationsHistory table, while the production database (root of your launching project) has it.
Maybe could be of help for somebody else.
I encountered the same issue with Sqlite In-Memory databases in my Tests. I have found the following thread https://github.com/dotnet/efcore/issues/4922. The point is ones all connections to the database are closed, the database is being removed from the memory. I have not solved the issue yet as I started using physical databases instead. But I will update my answer ones I find the solution.
My problem is even if I call db.Database.Migrate() first time without any other connections opened before, it still throws such error.

Can you create a database without migrations in EF5?

I am following the offical asp.net "Getting started with EF 5 using MVC 4". In that tutorial, the database is created when the migrations are performed(in my understanding). When I was looking at the EF 5 with Mvc 5 tutorial they didn't use migrations to create a database. They use database initializer. So, I was wondering could create a database for your project without using migrations in EF 5? Also, what would the difference be with both these approaches?
Code first Migrations and using Package Manager Console Commands to do upgrades can get a bit confusing at first.
You can use the initializer to CreateDatabaseIfNotExists , DropCreateIfModelChanges, DropCreateDatabaseAlways and to MigrateDatabaseToLatestVersion
See the interface IDatabaseInitializer<TContext>.
CreateDatabaseIfNotExists // is the Default initializer.
So this is why it appears EF just does things for you sometimes.
So the answer is "YES you can "Create a Database without Migrations"
But the difference is not obvious and if you would do that long term is another question.
If you are using migrations. It would Update the Db to match the code first model.
If there is NO database, then that means creating the database.
So Thats why Automated migrations and CreateDB look confusing since they can result in same outcome sometimes. But technically they are different.
So generally it is sufficient to use code first automatic "migrations" only.
Migrations can be either Automatic or "managed".
The managed migrations approach invovles generating code , tweaking the code and running PM commandlet or POwershell command to actually perform the migration.
With Automated migrations you just need set the intitializer and Access the DBContext.
There are 2 parts to the process.
a) The DB Initializer step.
do this immediately before instantiating YourDBContext.
//eg
// DONT TOUCH MY DB or i break your back!
Database.SetInitializer(new ContextInitializerNone<YourDbContext>()); // Do Nothing,
// OR
// yes migrate my db to match my code please.
Database.SetInitializer(new MigrateDatabaseToLatestVersion<YourDbContext, YourMigrationConfiguration>()); // Set to migration is requested, see config class below
The Confirguration class specified when using Migration initializer looks like this
public class YourMigrationConfiguration<TContext> : DbMigrationsConfiguration<TContext>
where TContext : DbContext{
protected YourMigrationConfiguration() {
AutomaticMigrationsEnabled = true; // run it when needed. Do not wait for my PM Command
AutomaticMigrationDataLossAllowed = true; // if the new db look means dropping tables or columns go ahead and kill my data. So use this option with caution.
}
then just trigger the migration in code when required.
Context.Database.Initialize(true); // i place this inside a method on my UoW class
Code first Db initialization strategies.
Code first migrations recommended reading
Managed Migrations
There are many articles on the web on this topic.

How to delete and recreate from scratch an existing EF Code First database

I am using EF Code First with EF 5 in VS 2012. I use PM update-database command and I have a simple seed method to fill some tables with sample data.
I would like to delete and recreate my x.mdb. The update history seems to be out of sync. If I comment out all my DBSets in my context, update-database runs with no error but leaves some tables in the DB. As I have no valuable data in the DB it seems to the simplest to reset the all thing.
How can I accomplish this?
If I'm understanding it right...
If you want to start clean:
1) Manually delete your DB - wherever it is (I'm assuming you have your connection sorted), or empty it, but easier/safer is to delete it all together - as there is system __MigrationHistory table - you need that removed too.
2) Remove all migration files - which are under Migrations - and named like numbers etc. - remove them all,
3) Rebuild your project containing migrations (and the rest) - and make sure your project is set up (configuration) to build automatically (that sometimes may cause problems - but not likely for you),
4) Run Add-Migration Initial again - then Update-Database
If you worked the correct way to create your migrations by using the command Add-Migration "Name_Of_Migration" then you can do the following to get a clean start (reset, with loss of data, of course):
Update-database -TargetMigration:0
Normally your DB is empty now since the down methods were executed.
Update-database
This will recreate your DB to your current migration
For EntityFrameworkCore you can use the following:
Update-Database -Migration 0
This will remove all migrations from the database.
Then you can use:
Remove-Migration
To remove your migration.
Finally you can recreate your migration and apply it to the database.
Add-Migration Initialize
Update-Database
Tested on EFCore v2.1.0
Similarly for the dotnet ef CLI tool:
dotnet ef database update 0 [ --context dbcontextname ]
dotnet ef migrations add Initialize
dotnet ef database update
Single Liner to Drop, Create and Seed from Package Manager Console:
update-database -TargetMigration:0 | update-database -force
Kaboom.
How about ..
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<ExampleContext>());
// C
// o
// d
// i
// n
// g
}
I picked this up from Programming Entity Framework: Code First, Pg 28 First Edition.
dbctx.Database.EnsureDeleted();
dbctx.Database.EnsureCreated();
I am using .net Core 6 and this code is directly stripped out of the Program.cs
using Microsoft.EntityFrameworkCore;
namespace RandomProjectName
{
public class Program
{
public static async Task<int> Main(string[] args)
{
var connectionString = "Server=YourServerName;Database=YourDatabaseName;Integrated Security=True;";
var optionsBuilder = new DbContextOptionsBuilder<YourDataContext>();
optionsBuilder.UseSqlServer(connectionString);
var db = new YourDataContext(optionsBuilder.Options);
db.Database.EnsureDeleted();
db.Database.Migrate();
}
}
}
You should have at minimum initial migration for this to work.
There re many ways to drop a database or update existing database, simply you can switched to previous migrations.
dotnet ef database update previousMigraionName
But some databases have limitations like not allow to modify after create relationships, means you have not allow privileges to drop columns from ef core database providers but most of time in ef core drop database is allowed.so you can drop DB using drop command
and then you use previous migration again.
dotnet ef database drop
PMC command
PM> drop-database
OR you can do manually deleting database and do a migration.
If you created your database following this tutorial: https://msdn.microsoft.com/en-au/data/jj193542.aspx
... then this might work:
Delete all .mdf and .ldf files in your project directory
Go to View / SQL Server Object Explorer and delete the database from the (localdb)\v11.0 subnode. See also https://stackoverflow.com/a/15832184/2279059
Using EF6 with ASP.Net Core 5 I found these commands handy during first initialization of the database:
Remove-Migration -force; Add-Migration InitialMigration; Update-Database;
It removes the last migration (should be the only one), creates it again, then refreshes the database. You can thus type these three commands in one line into the Package Management Console after editing your DbContext and it'll update InitialMigration and database.
A little annoying is that it'll compile your project three times in a row but a least no further manual steps (like deleting the migration files) are necessary.
When you remove an entity you'll need to issue Remove-Database before updating. So the line becomes:
Remove-Migration -force; Add-Migration InitialMigration; Remove-Database; Update-Database;
Problematic here: You need to confirm removing the database + 4 rebuilds.
Take these steps:
Delete those object which should be deleted from the context // Dbset<Item> Items{get;set;}
and in Nuget Console run these commands
add-migration [contextName]
update-database -verbose
It will drop table(s) that not exist in Context, but already created in database
Let me help in updating the answers here since new users will find it useful.
I believe the aim is to delete the database itself and recreate it using EF Code First approach.
1.Open your project in Visual Studio using the ".sln" extention.
2.Select Server Explorer( it is oftentimes on the left)
3.Select SQL Server Object Explorer.
4.The database you want to delete would be listed under any of the localDB. Right-Click it and select delete.
Since this question is gonna be clicked some day by new EF Core users and I find the top answers somewhat unnecessarily destructive, I will show you a way to start "fresh". Beware, this deletes all of your data.
Delete all tables on your MS SQL server. Also delete the __EFMigrations table.
Type dotnet ef database update
EF Core will now recreate the database from zero up until your latest migration.

Retry a flyway failed migration

I'm just in the process of configuring and fully understanding flyway and I came into this situation:
I successfully configured a new project to work with flyway.
I successfully migrated a test database from version 0 to 1.0.3.
Migration to version 1.0.4 failed to execute. (I was trying to add column that was already there, no problems so far, my bad.)
However, once that I made the necessary changes to the corresponding script to work, flyway kept showing this message:
Current schema version: 1.0.4
com.googlecode.flyway.core.migration.MigrationException: Migration to version 1.0.4 failed! Please restore backups and roll back database and code!
Since I didn't want to restore a complete dump and apply every migration again, just to make an alter table script to work, what I finally did were some changes to the 'schema_version' table:
1st I erased the entry for version 1.0.4
2nd I set the 'current_version' field to 1 for version 1.0.3
And then executed the flyway:migrate command again
After this, the migration finally was applied and a success message shown, however I´m not quite sure if this is the right approach to deal kind of this situations. I'm no sure if its right to modify the 'schema_version' table by myself since i think it should only be modified by flyway itself.
So, after explaining what happened to me, my question would be:
Is there a way to 'retry' to apply a failed migration in flyway, without modifying the 'schema_version' table by myself?
Any command I'm not aware of to fulfill this task?
This is answered in the FAQ: http://flywaydb.org/documentation/faq.html#repair
The upcoming Flyway 2.0 will include the repair command. This code is already checked into SCM.
Note: This only deals with Flyway's metadata table. You are still responsible for cleaning up any other effects of a failed migration.
Update: Flyway 2.0 has now been released. You can grab it at http://flywaydb.org
I don't know whether this a good idea or not, but you could try doing a repair() if migrate() fails:
final Flyway flyway = new Flyway();
flyway.setBaselineOnMigrate(true);
flyway.setValidateOnMigrate(false);
flyway.setDataSource(dataSource());
try {
flyway.migrate();
} catch (final Exception e) {
logger.error("Flyway migration failed, doing a repair and retrying ...");
flyway.repair();
flyway.migrate();
}
Full example, this will always try to repair before running a migration, the rest of configuration in in a config file.
#Configuration
public class PersistanceConfiguration {
protected final Logger log = LoggerFactory.getLogger(this.getClass());
#Bean
public FlywayMigrationStrategy cleanMigrateStrategy() {
FlywayMigrationStrategy strategy = new FlywayMigrationStrategy() {
#Override
public void migrate(Flyway flyway) {
flyway.repair();
flyway.migrate();
}
};
return strategy;
}
}

Resources