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;
Related
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");
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 am creating a simple application that uses a database derived from db = SQLiteDatabase.openOrCreateDatabase(...). Now, when I create it I use db.setVersion(1);
And I read somewhere that I have to change the database version each time I change it. Now I can't find the particular tutorial where I read this, so I am left with some questions.
1)What is the reason behind versioning of a database? What is a practical purpose?
2)When exactly should the version be updated? After every insert? Every additional table added?
3)Will I be in trouble if I don't update the versions after 1? What would it lead to?
1)Versioning the database is really versioning your schema. This allows you to know when the schema is changed so you can convert it.
2)Whenever you change the schema.
3)If you change the schema, you won't know which one is being used and will end up with exceptions. If you never change the schema, nothing will happen.
And you shouldn't be manually calling setVersion. It already knows the version for an existing one, and you pass in the version elsewhere if its a new database.
The SQLite Database Version In Android is only neccessary if you manage database creation and version updates with the SQLiteOpenHelper.
SQLiteOpenHelper takes care of
opening the database if it exists,
creating it if it does not exis,
upgrading its schema if necessary
sets the SQLite Database Version.
The databaseverionnumber is set in the SQLiteDatabase-constructor.
Your example SQLiteDatabase.openOrCreateDatabase(...) does not use SQLiteOpenHelper so in this case there is no need set the dbversion.
In my android app, I was using a standard SQLite database with a helper class that had 1 table with 3 columns. In the most recent update I had to add another column of to the table, but some users have reported crashes, which (judging by the stack trace) I think comes from the new version trying to read from a column that does not exist because the data is from the old version. How can I protect the users' data between updates short of a manual backup and restore?
Here is the link to the complete updated database class:
https://github.com/cjbrooks12/scripturememory/blob/working/src/com/caseybrooks/scripturememory/databases/VersesDatabase.java
SQLiteOpenHelper will handle the database versioning, you will just have to provide it with proper database version numbers and overridden callbacks. Looking at your code:
Your DB_VERSION is 1. When you change the database schema between released versions, you should increment this number. The version number is stored in the database file, and if the version provided in code is different from the one stored in file, onUpgrade() or onDowngrade() will be called accordingly. In your case, since the database file already exists, no onCreate() was called and since the version numbers matched, no upgrade was performed.
Your onUpgrade() drops the table and then recreates it. In some cases this might be ok, say, it's just a cached copy of data stored elsewhere, but usually as a user, I don't want an app upgrade to delete my data. Implement onUpgrade() so that it does the necessary schema modifications while preserving data. Some generic strategies for this:
If it's just adding some columns ALTER TABLE and put some suitable default values.
If it's more complex schema change, rename the old tables to temporary names, create new tables and then migrate data from the temp tables.
In any case, after onUpgrade() the database schema should be in the same shape it would be if onCreate() was called to create a new database, but with existing data preserved.
I've got an Android app I'm about ready to release, and I'm reviewing some of my code. I'm worried about my implementation for my SQLiteOpenHelper. Specifically, I want to verify what the oldVersion and newVersion reference in the onUpgrade method. Is this based upon the versionCode in my AndroidManifest.xml? Or is this value something completely separate, specific to the database? If it's the latter, how does the database determine the version?
Is this based upon the versionCode in my AndroidManifest.xml?
Not normally, unless you upgrade your schema every time you publish an upgrade to your app, and even then the "based upon" would be mostly coincidental.
Or is this value something completely separate, specific to the database?
Yes. You increment the version every time you have a new database schema.
If it's the latter, how does the database determine the version?
On every onCreate() and onUpgrade(), Android sticks the then-new version of the database schema in a metadata table in the database. That's what Android then checks when you use your helper in the future, comparing that stored value to the one you provide in your SQLiteOpenHelper constructor.
while you solved your question, that you can determine it just yourself on creation. I want to leave this for persons wondering:
how does the database determine the version..
.. if the database already exists?
it is stored with the db file and accessible via PRAGMA user_version; as noted in SQLiteOpenHelper.java:getVersion().