I have used realm database(iOS and Android both). It worked well still now and migration. When migration, I could add table and additional columns in updated schema. By the way, I have no idea whether I'm capable of extracting previous table data and move to new schema table. Please let me know about this.
Just to confirm, you've successfully managed to perform a schema migration with Realm on both the iOS and Android versions of your app, but your question is whether you can extract data from a table in an older schema version and move it to a new table in your latest schema version. Is this correct?
If this is correct, then yes. At the time of performing a migration, you can run a loop inside your MigrationBlock block/RealmMigration object to manually copy the data from an older table to a newly created one.
Examples of this logic can be found in the sample code of both the iOS and Java repositories on Realm's GitHub account.
Unfortunately, once a migration has completed on a Realm file and the previous table has been deleted, then it's not possible to back-track and extract the data at a later time.
You could do something like this:
RealmSchema schema = realm.getSchema();
schema.get("OldTableName").renameField("OldFieldName", "NewFieldName");
schema.rename("OldTableName", "NewTableName");
Related
Should I increment the value of the Room database version if I change the content of the database when its migration strategy is set to "fallback to destructive migration"?
Following changes made to database:
Some columns are removed.
Content of some rows is updated in the database file that is stored in assets.
Yes. You should update the version of the database even with fallback to destructive migration strategy. Room uniquely identifies every database version with an "identity hash string", which is kept in a configuration table.
Keeping the database version unchanged will cause the app to crash with an IllegalStateException. Internally Room checks the identity of the database comparing the identity hash of the current version vs the the one stored in the table called "room_master_table".
You can learn more about this in the below article which also explains in detail how to handle version change and testing.
Reference: https://medium.com/androiddevelopers/understanding-migrations-with-room-f01e04b07929
UPDATE: It is interesting that the app crashed in some users, but for some users including me, it didn't crash. So it's better to update the version of the database even though its migration strategy is fallback to destructive.
From my experience, it seems we don't have to increment the value of Room database version when its migration strategy is set to "fallback to destructive migration".
I changed the content of the database and removed some columns from the database file.
Then I installed the previous version of the app (unchanged database). Then I used the application and made sure a database instance is created.
Then I installed the new version of the app (changed database). And it didn't crash and everything worked fine. Changes applied to the database.
I want to update my app at play store with bug fixes. APP already uses Room DB. Do i need to migrate the DB. There is no change in the DB. There are only UI changes. Does new version effect the people DB, who are already using it. Can someone provide the details about this.
Thanks in advance.
There is no change in the DB.
The database remains and you do not need to change the version of the database (as per the #Database( .... version=?)).
You only need to change (increase) the database version if the schema has changed.
If you increase the version number and do not have a migration (migration class to call) to cover that version, then an IllegalStateException will occur unless you have .fallbackToDestructiveMigration() which WILL delete and recreate the database (effectively empty the database with the ne schema).
You can also use fallbackToDestructiveMigrationFrom()
It is the version number that determines if a database migration is required. However, if a change is made and if any of the entities mismatch the database when the .build method is run then an exception will result.
If you change an Entity (the schema) and do not increase the version number you will get an IllegalStateException with the message starting with Room cannot verify the data integrity. This is because the hash stored in the room_master_table has changed.
If you changed the database schema outside of room then you'd get an exception indicating that the expected schema (the database according to the Entities) does not match the schema found (the database according to the actual database).
In your situation I'd suggest not changing the version number.
You may wish to have a look at:-
Migrating Room Databases
#Database
fallbackToDestructiveMigration
fallbackToDestructiveMigrationFrom
I'm trying to figure out the best way to handle database upgrades and versioning.
At the moment I delete the database and log users out when I do a point release, which isn't a great experience.
Can anyone recommend any tips for doing this?
Your database version is independent of your app version. If your database schema doesn't change at all, you shouldn't need to do anything to your database during an update.
When your database schema changes, you should handle database updates in onUpgrade() of your SQLiteOpenHelper. This method is called when you try to access your database and you have updated your database version, as described in the Data Storage Options documentation.
If you are using a third party library to handle your databases, it should either handle the upgrade for you or provide similar functionality.
There is no universal strategy for upgrading your database here. What you do depends completely on what your schema looked like before the upgrade and what the new schema looks like. Depending on what changed, you might create new tables or columns, delete tables or columns, update rows in the database, or move data between tables. If you have a specific question about how to migrate your data, create a new question describing the new and old schemas.
The way we do it is that we run a routine every time the app starts that calls a stored proc on the server to get SQL that upgrades the database if it is necessary. (The sql can be quite involved: dropping tables and recreates them with new structures and inserting new values). We store the version of the database in the database itself and upgrades to the new version.
We don't use the onUpgrade() call.
i have the problem that when i release new version of my application, if i add a new column to one of my db tables, the database doesn't update. Any one know how to create a script of upgrade versione in case there are new columns or new tables??
Thanks
You have to remember that CreateTable it's already doing the columns update for you, because internally it calls a method called MigrateTable.
However you could have to handle more advanced modification to your database, like adding triggers or something similar.
In that case i suggest you to perform modifications manually.
In Xamarin Forms i've ended up with this:
https://gist.github.com/matpag/b2545cc22c8e22449cd7eaf6b4910396
Could not be the best strategy ever but seems to work for me.
Summarizing :
You have to save the database version in an internal flag of the SQlite database called user_version accessible with PRAGMA keyword.
Every time you get the database connection, you have to perform a check and see if the current database version is the same as the app last database version.
If not you need to perform a database update and set the new current version.
It's not a matter of a script, as there isn't such a thing. You can release a version with a "patch" that will run once, extracting all your records to a temporary form -> deleting the table -> creating it again (will assure it's created with the new columns and so on) -> reinserting the records again. After a while, when you know that all your users (or whenever you set the limit) have moved to the newer version you can just eliminate the "patch" from your code.
Hope it helps.
The automatic migration feature is still not working in sqlite.net-pcl, but it looks like it does work in the other sqlite package: sqlite-net-pcl, which is actually the Xamarin recommend sqlite package.
I have the following scenario:
My app is published with database version 4 to the customers.
I did some bugfixes and added some more features. This process also changed my models and thats why the database changed too.
How can I check what database version the customer has installed on his devices and migrate the old data to the new database? Is there an onUpgrade method or something like this in the ActiveAndroid Library?
After taking a deeper look into ActiveAndroid's sourcecode I found a solution.
ActiveAndroid can use sql-scripts located in your asset folder to migrate from one version to another.
It sorts all your sql files located in assets/migrations/ using a natural sorting algorithm:
Each SQL script which was found will be executed if its > oldVersion and <= newVersion
if you access your db via SQLiteOpenHelper and do proper db versioning than you can use it's onUpgrade method to run some code to update your db. Othewise you should do your custom solution.
I suggest that you create a class which extends SQLiteOpenHelper. When your database is opened through this class, it will automatically call the onUpgrade() method when necessary. The parameters to this method include the new and old version numbers of your database schema.
Whenever your schema changes you need to increment the database version number, either through Configuration or AA_DB_VERSION meta-data. If new classes are added, ActiveAndroid will automatically add them to the database. If you want to change something in an existing table however (e.g. add or delete a column), this is done using sql-scripts named <NewVersion>.sql, where NewVersion is the AA_DB_VERSION, in assets/migrations.
ActiveAndroid will execute a script if its filename is greater than the old database-version and smaller or equal to the new version.
Let’s assume you added a column color to the Items table. You now need to increase AA_DB_VERSION to 2 and provide a script 2.sql.
ALTER TABLE Items ADD COLUMN color INTEGER;