I need to write unit case for realm.io migration. How do i simulate a before and after Object Class?
One solution is to have a realm file previously saved (such as in your unit test bundle) with the schema version from which you want to test the migration. Your realm object in code is kept in its most recent version, while the realm schema in disk contains an older version.
Have a look at the migration sample app.
In the sample there are versions V0, V1 and V2 of the same Person object, as well as three different realm database files with different schema versions default-v0.realm, default-v1.realm and default-v2.realm.
The same migrationBlock is then used in all versions of the database to ensure it can correctly bring any possible old schema to the newest V2.
Related
I have a little problem with the order of the migrations. The fact is that in my database there is a "Products" model whose migration is one of the first in the history list, call it 001_products. After this migration, others are executed that make inserts in this same table (some inserts necessary for the basic operation of the application), called migration 002_inserts_products.
The problem appeared when modifying the "Products" model, call it 003_modify_products migration. The migration was applied after the inserts and made the tests fail (tests that generate a test database doing all the migrations), which followed this order:
001_products
002_inserts_products
003_modify_products
The solution then was to add a dependency on migrations that made inserts in "Products" with respect to the subsequent migration that modified that table. That is, make 002_inserts_products dependent on 003_modify_products.
However, this, which worked in the tests and locally (where the modification in "Products" had already been applied), does not work in production, since there the migration that has not been applied is the one that modifies the "Products" model ".
That is, the panorama in production is:
[X] 001_products
[X] 002_inserts_products
[ ] 003_modify_products
When trying to do the new migration, the error that appears is:
django.db.migrations.exceptions.InconsistentMigrationHistory: Migration 002_inserts_products is applied before its dependency 003_modify_products on database 'default'.
The question is how to set the migrations to work both in test and in production (that is, in the context that the previous migrations have already been done)?
Unfortunately, you're trying to find a solution for a problem you created yourself by modifying an older migration to make it dependent on a newer migration to get around your tests failing.
The proper solution would be to do the following:
Remove 002_inserts_products's dependency on 003_modify_products, and return it to its original state.
Add 004_update_products to update any products inserted via 002_insert_products so that they work with the table modifications in 003_modify_products.
Update your tests to accommodate the changes made in 003_modify_products.
It's never a good idea to change the expected ordering of migrations that have already run, because while it might work in your local environment, it's very likely to blow up when you're deploying to a server on which none of those migrations have run.
Also remember that tests failing is not always indicative of something you've done wrong -- tests, especially database tests, are not necessarily future-proof. It's totally normal to have to update tests due to schema changes.
I am trying to remove a model from Realm. I appears there's a straightforward way to do it in Java with
realm.getSchema().remove(className)
It doesn't appear there is an option in Swift 3 other than to remove the model from the App and then migrate the data, or delete the entire Realm file.
To clarify, when I open the Realm Browser I have three models
Dog 2
Person 4
Test 0
and I want to remove just the Test model via code. There doesn't appear to be any way to remove it via the Browser either.
Perhaps I overlooked something in the docs?
No, you haven't overlooked anything in the docs.
It is not possible to modify the schema of a Realm file in the Objective-C/Swift SDKs without triggering a migration. In which case, you can use Migration.deleteData(forType:) to delete the object schema from the Realm.
Additionally, if you want to explicitly ensure that Test isn't added to your Realm file in the first place, you can explicitly define that in your Realm configuration.
Is there a way to ignore errors when running a manual migration?
We have client databases in different states and I need to get them all updated to the latest version.
The reason I ask about ignoring errors is because I just want to code my migration like this
public override void Up()
{
AddColumn("ClientUser", "LastSyncTime", c => c.Guid());
AddColumn("ClientUser", "FileTransferToken", c => c.Guid());
AddColumn("ClientUser", "DateFileTransferTokenIssued", c => c.DateTime());
}
but naturally and expectedly it will throw an exception where the column already exists.
No. It is not supposed use case for EF Migrations. Migration drives database from one defined state to another defined state. If you have database in different states you need multiple migrations each covering just part of the transition.
If you want to start to use migrations in existing project with multiple databases you should first move all your databases to the same state without migrations and start to use it as initial state after which all changes will be handled only through migrations. Otherwise you will have a lot of problems.
This doesn't answer your specific question, but it may be an answer for your problem.
Use the Database Project in VS 2010 to create a schema of your target database.
You can use this "Gold Standard" schema to compare your other databases that are in different states and produce a delta script to take it from its current schema to the target schema.
Once you are at a known state across your databases, then switch to the Database Migrations for the schema moving forward.
Keith
I'm using the entity framework.
In one of my unit tests I have a line like:
this.Set<T>().Add(entity);
On executing that line I get:
System.InvalidOperationException : The model backing the
'InvoiceNewDataContext' context has changed since the database was
created. Either manually delete/update the database, or call
Database.SetInitializer with an IDatabaseInitializer instance. For
example, the DropCreateDatabaseIfModelChanges strategy will
automatically delete and recreate the database, and optionally seed it
with new data.
Well I've actually deleted the database and removed the connection string.
I'm surprised this error is happening on adding as I wouldn't expect it to happen until I saved the data and it discovered there was no database.
In previous projects/solutions I created during unit tests I have been able to add to the context for test purposes without actually calling SaveChanges.
Would anyone know why this would be happening in my latest projects/solutions?
Are you sure it really didn't use database in your previous projects? If you do not specify any connection string it will silently use a default one to SQLExpress database with local .mdf file so make sure that isn't happening now.
Is it possible to unit test Entity Framework v2 repositories with SqLite? Is this only possible if my entities are plain Poco and not automatically generated by Entity Framework?
I've generated a entity model from SqlServer and in the generated .edmx file i found this in section SSDL content: Provider="System.Data.SqlClient". Correct me if I am wrong, but shouldnt that be System.Data.SQLite in order to work with sqlite?
Its only possible if two entity models are created (one for each provider) and then make both object contexts implement the same interface.
Its not worth the effort to manage two entity models.
I hope this get fixed in Entity Framework Ver 3.