when I created a migration, I inserted some data, but the newly installed app did not perform the migration.
do I need to insert/update data on the onCreate call every time I migrate?
Migrations won't run if you install the app, as no Database exists so it is created.
Migrations are designed to handle new versions of the App being published and specifically new versions that also change the Room database version.
do I need to insert/update data on the onCreate call every time I migrate?
NO! onCreate will not run, it only runs once automatically for the lifetime of the database (unless you call it from the Migration).
For an App to be installed, it cannot exist and thus must be uninstalled, the uninstall deletes all the App's data including the databases.
You should be doing what is required in the Mirgation code and then it depends on what you do. e.g. :-
If adding a column for instance and you use the ALTER TABLE your_table ADD COLUMN the_new_column_definition then the existing data is preserved.
If adding a new table then there is no issue.
If however you wanted to change a column's definition (other than it's name) then you have to drop and recreate the table. What would typically be done would be to create the new table, populate it from the original table, rename or drop the original table and the rename the new table to be the name of the original table.
You may wish to have a look at SQLite ALTER TABLE
Related
Imagine I deliver a prepopulated database with my application version 1.
The prepopulated database includes a table "my_items" with the column item:
item
------
apple
For application version 2 I deliver an updated prepopulated database, so table "my_items" includes
item
------
apple
milk
How would one make sure that the new prepopulated data is transfered to the database of the app in a non-destructive way? (user is allowed to insert new items to "my_items" by himself and I need to keep his input). I read the Room migrations documentation, but it seems like the prepopulated data is only read on a destructive migration, which is not what I want, as the items entered by the user himself shall remain available.
Room's built in migration processing does not support the merging of existing data into a new prepopulated database.
An approach that should work is to give the prepackaged database file for each app version a unique name, e.g. my_items1.db, my_items2.db, etc. In app version 2, create the main database from prepackaged database file my_items2.db. Then open the database for the previous version as a separate Room database instance, query it to find the items added by the user, and insert those into the new main database with appropriate default values for new fields. This merge processing could be triggered by the onCreate() callback for the main database. The merge processing should be done in a transaction. If it completes successfully, you can close and delete the database for the previous version. In the event of failure, you'll need to notify the user and implement some sort of mitigation processing.
i have developed a tutorial app in which i have saved more than 500 questions and answers.
their is one more table called favourites. which is for user input.
now, i want to update my app with new questions and answers.
but i dont want to erase the data of favourites table (in case, user has marked some questions favourites, so those questions should not be erased from favourites)
so how can i do it?
because, i have used SQLassethelper library for database connectivity.
my old db contains:
data table(static table)
favourites table(local table)
so, according to sqliteassethelper documentation i added my new db:
that contains: updated data table. i didnt inserted favourites table here coz it will be created in script file.
and stored that db in assets>>databases folder.
then
i created a script fild
db.db_upgrade_1-2.sql
alter table "favourites" rename to "favourites_tmp";
create table "favourites" (
"id" Integer not null primary key autoincrement unique,
"question" text,
"answer" text,
"category" text,
"catid" integer
);
insert into "favourites" ("id","question","answer","category","catid") select from "favourites_tmp" "id","question","answer","category","catid" from "favourites_tmp";
drop table "favourites_tmp";
so i think here favourites table will be created with old data.
but
when i run the project, it says: no such tabld favourites.
The documentation tells you to
create a text file containing all required SQL commands to upgrade the database from its previous version to it's current version.
You can use any SQL commands, not only ALTER TABLE, but also INSERT.
The database file in the assets folder is used only if there is no old data (if the app is installed for the first time). If there is old data, SQLiteAssetHelper executes the SQL upgrade script instead.
The SQLiteAssetHelper project contains an example that shows how such a script would look like.
To keep the data in the favourites table, you do not need to do anything.
To add the new question/answers, use a bunch of INSERT statements.
(For how to get those INSERT statements, see How to compare two SQLite databases.)
finally i got answer for my questions.
as i said i am using SQLiteAssetHelper library.
and now i want to add new records and want to release the update version.
so i was finding the feature by which i can store new updated db in assets folder. and this library will update the old db in user's phone. with keeping particular table in old db.
but currently this library doesnt offers such feature.
the upgrade script can be use only to make changes is old db. we can add new updated db and copy the data from new one.
if we want to add new data and also dont want to erase local data table.
then we need to write insert queries in upgrade script as described in documentation of that library.
but if we have to add 100 queries then their is no shortcut for it.
we have to write 100 insert statements in upgrade script.
and in case if we gate a error saying
cannot upgrade read only database from version x to y then
here is the solution for it:
SQLITE cant upgrade read-only database from version 1 to 2
I have already uploaded one apk file for one of the project, now i am updating apk with updated column in my database table,so i dont want to loss previous apk db table data.
so please help me out from this.
Thanks,
Dhiraj
Use SQLiteOpenHelper and implement onUpgrade(). You are passed the old and new database schema versions, and you can then perform an in-place modification of your database structure (e.g., run ALTER TABLE statements using execSql() on the supplied SQLiteDatabase instance).
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 hava an android application which consists sqlite database in the assets folder.
In the DB I have several tables, which one of them is user data (which is updated over time by using the application - when the user installs the application this table is empty).
The other tables store data that I update.
The question is: when a user gets an updated version of my application (with sqlite database in the assets folder) from the market, I need to keep the data the user updated by using the application, but i do want to update the other tables (which consist my data).
What is the correct way to do it?
Thank You :)
Keep a version number for each change and implement the onUpgrade method for the possible combinations. See more in the javadoc for SQLiteOpenHelper
Since you said your tables are empty when the Database is first created, it shouldn't be necessary to add the Database from the /assets-folder.
Instead, you can use a SQLiteOpenHelper, which offers an onCreate()-method that can do the initial table-creation (an add some example data if necessary).
If you then update your app, you simply increase the Database-version and the onUpgrade()-method is called, where you can then perform the Database update.
See this other question: Run some code when user update my app
If your app comes with a huge Database and inserting entry's in the SQLiteOpenHelper isn't the right way to go, you can still check if the Database already exists and then do the updating (through the onUpgrade()-method) and keep the users data.