During an app update via the App Store I want to update the SQLite database file with more content.
The old SQLite file is in the Documents folder of my app.
How do I handle this?
I'm assuming you're not using Core Data or else you'd be using the auto-migration feature. For straight SQLLite you'll want to create a new database file. Then depending on the nature of your schema changes, you might be able to execute a query to copy the data over (using INSERT INTO destination SELECT * FROM source) . But if the changes are too much to handle with a simple set of queries, for example if it involves business logic, then you might need to write a script to convert the old data from one database to the new one.
sqlite> attach 'path_to_table.db3' as toMerge;
sqlite> insert into MyTableToInsertTo select * from toMerge.MyTableToInsertFrom;
sqlite> detach database toMerge;
use BEGIN; COMMIT; for large data
link
Related
I am writing a quiz-style app which is populated from a SQLite database through FMDB. I have copied the database from the app bundle to the app documents directory so that I have read/write privileges and can therefore save user data such as scores to the database as well.
However, I need a way to compare the database in the app documents with the database in the app bundle, so that updates to the bundle db (e.g. new questions) can be copied to the docs db. Simply copying the entire bundle db over to app docs isn't an option as this would overwrite previously saved user data. I had some sort of differences statement in mind such as
SELECT questionID FROM Bundle.Master EXCEPT SELECT questionID FROM AppDocs.Master
to look at what had changed and go from there, but I'm unsure how to use the executeQuery command with more than one db simultaneously.
Any thoughts/alternative approaches appreciated.
You could ship your bundled db with a "version", and copy this version along with other tables in the documents db. On app start up, compare the version of the bundled db with the version of the documents db, and perform a new import if necessary.
You'd have all the opportunities to perform any db migration and (re)import exactly as it needs to be done.
I have some general questions about iphone app updates that involves sqlite db.
With the new update does the existing sqlite db get overwritten with a copy of the new one?
If the update doesn't involve any schema changes then the user should be able to reuse the existing database with their saved data, right? (if the existing database doesn't get overwritten from 1 above )
If there are some schema changes, what's the best way to transfer data from the old database into the new one? Can some one please give me guidelines and sample code?
Only files inside the app bundle are replaced. If the database file is in your app's Documents directory, it will not be replaced. (Note that if you change files inside your app bundle, the code signature will no longer be valid, and the app will not launch. So unless you are using a read-only database, it would have to be in the Documents directory.)
Yes.
What's best depends on the data. You're not going to find sample code for such a generic question. First, you need to detect that your app is running with an old DB version. Then you need to upgrade it.
To check versions:
You could use a different file name for the new schema. If Version2.db does not exist but Version1.db does, do an upgrade.
You could embed a schema version in your database. I have a table called metadata with a name and value column. I use that to store some general values, including a dataversion number. I check that number when I open the database, and if it is less than the current version, I do an upgrade.
Instead of creating a table, you could also use sqlite's built-in user_version pragma to check and store a version number.
You could check the table structure directly: look for the existence of a column or table.
To upgrade:
You could upgrade in place by using a series of SQL commands. You could even store a SQL file inside your app bundle as a resource and simply pass it along to sqlite3_exec to do all the work. (Do this inside a transaction, in case there is a problem!)
You could upgrade by copying data from one database file to a new one.
If your upgrade may run a long time (more than one second), you should display an upgrading screen, to explain to the user what is going on.
1) The database file isn't stored as part of the app bundle so no, it won't get automatically overwritten.
2) Yes - all their data will be saved. In fact, the database won't get touched at all by the update.
3) This is the tricky one - read this fantastically interesting document - especially the part on lightweight migration - if your schema changes are small and follow a certain set of rules, they will happen automatically and the user won't notice. however, if ther are major changes to the schema you will have to write your own migration code (that's in that links as well)
I've always managed to get away with running lightweight migrations myself - it's by far easier than doing it yourself.
What I do is that I create a working copy of the database in the Documents directory. The main copy comes with the bundle. When I update the app I then have the option to make a new copy over the working copy, or leave it.
I have app in that i am using coredata. And when i install the app three files are getting created in the document directory called “test.sqlite, test.sqlite-shm and test.sqlite-wal". And now in second app i copy the test.sqlite in the folder and i want to access the database and tables but i got error like this "no such table found". Is there any issue that i create the database with coredata? please help me.
You either need to:
send all of the sqlite* files that Core Data creates
export the content from the data store, format it and send that
Option 1 should work and be fast to implement, but it isn't very future proof. Option 2 will take longer but is a much better solution.
I'm programming an iPhone app using a sqlite database. Every year, I need to update the database from a server.
Now I have two questions:
Should I update the database or should I overwrite the older database (The sqlite file is approximately 2MB)?
How would I do that?
It depends on how many data you wanna change from the old database. If just few data need to be changed, just update the DB, otherwise replace it.
Here is how to update the DB:
Download the script file to iPhone
Parse the script into an sql command list
Run the sql command for updates
I'm using a sqlite database in my iOS app. I have all its tables definitions in an .sqlite file I've placed in the "Supporting Files" group of the Xcode project, and in code I copy this file to "Documents" to be able to perform database operations. While developing, I've found that, when I need to add/remove a table or change its fields and I remove the .sqlite file from "Supporting Files" to add the new one, then I need to uninstall the app from the device or the simulator and build again to get the new database.
How could I make changes in database tables by replacing the .sqlite file without having to uninstall the app? When the app will be submitted to the App Store, will the users have to reinstall the app when a new update with changes in database is available?
EDIT. Is it possible to replace the database and to keep/copy the data the user had in the old one? Or will user loose all the stored data when downloading an app update from the Store where the .sqlite database is replaced, as if he were installing the app from scratch?
I've never submitted an app to the Store yet, I need some guidelines about how to handle app updates if I need to make changes in database tables when having such database in an .sqlite file. I'm not using Core Data.
Thanks
for it, you need to modify database by using programmatically. Means, if you want to create/add new table in database then you need to add code like Create Table.... In this case, you can't use predefine database in code.
But if you want to use database instead of writing code, then you need to rename your database and copy all old database data to new database programmatically.
Thanks