agrosner / DBFlow

A blazing fast, powerful, and very simple ORM android database library that writes database code for you.
MIT License
4.87k stars 598 forks source link

Migrations/Lookup Tables #700

Closed moworld closed 8 years ago

moworld commented 8 years ago

I have posted a question to SO. I don't think this is a DBFlow "issue", it's probably a me "issue", but I wanted to post here in the hopes you can help. The short versions is:

How do I get Migration 0 (initialize) to work? Should I use it for this purpose?

Code @ Github. Thank You.

agrosner commented 8 years ago

Can clarify "to work". You can place a migration at version 0 to do some initialization work. I will have better docs on this by next week, but you must reference the DatabaseWrapper in onMigrate() for queries and inserting data.

Instead of Model.save() you have to use FlowManager.getModelAdapter(SomeTable.class).save(model, wrapper); and etc for migrations. its so we don't recursively access the database.

moworld commented 8 years ago

Here's is what I've tried: I have the following migration defined: PopulateGamesData.java Here is the database declaration: BracketsDatabase.java

I'm not actually trying to insert records yet, I'm just printing to the LogCat. My assumption is that the migrate(SQLiteDatabase database) method will be run on initial install of the app, but nothing is showing up in the LogCat. I have also tried reinstalling the app, with the database and migration versions increased by 1.

moworld commented 8 years ago

Ok, so I think the problem might be that the database is not even getting created until I try to put data into it, and the migration doesn't happen unless the database exists. I added an Insert() to my main activities' onCreate, then ran the app (BTW, this is on a device, not emulator). This time, the migrate() callback ran.

If this is the case, it's difficult to see how to use a 0 migration for initialization, because the migration won't run until the database is initialized. Is there simple way to force the database to get created in the Application class, then initialize table data in a migration? Or, should I just used a Shared Preference to determine if it is a first run, then Insert all the initial data in an Application class method?

Thank you for your help.

agrosner commented 8 years ago

yeah in new doc im writing you would need to add: FlowManager.getDatabase(BracketsDatabase.NAME).getWritableDatabase(); to get it initialized and start running migrations.

agrosner commented 8 years ago

also note that the migration only runs when DB is first created, wont be run on existing databases.

moworld commented 8 years ago

ok, cool. So I'm assuming I do that in Application class onCreate(), just after the FlowManager.init(this);?

the migration only runs when DB is first created

That's exactly what I want to load lookup data, I'll try it out. Thank you. For clarification, I could still add another migration (Version = 1) that would run on an existing database in the event it gets changed in the future, right?

agrosner commented 8 years ago

yep! cool. I am working on making this much more straightforward in next beta.

moworld commented 8 years ago

That works great, but I had to use TransactionManager.getInstance().saveOnSaveQueue(g);' becauseFlowManager.getModelAdapter(SomeTable.class).save(model, wrapper);` didn't work. Again, I'm not the most experience developer so I couldn't figure out how to wrap the SQLiteDatabase. Thank you for your help though. I am able to move forward with development.

agrosner commented 8 years ago

which version of DBFlow you using?

moworld commented 8 years ago

2.2.1

moworld commented 8 years ago

I learned about it and pulled the dependcies directly from this demo. I see now, that was an older version.

moworld commented 8 years ago

Which version do you recommend?

agrosner commented 8 years ago

ah. I see I recommend 3.0.0-beta5 and up, but since so much has changed its hard to say if migrations at 0 were working like they are now.

carmas123 commented 8 years ago

The best solution for me to migrate and keep database updated is to execute sql script direct. If you want I've make a custom DatabaseHelperDelegate and a DatabaseOpenHelper to do that. You must have an Assets resource with a subfolder migration like this:

demo

and when you must go to next version you must create another script wich their version. This is for me the best migration mode!! Because you have the full control over database structure and data.

moworld commented 8 years ago

I'm all upgraded and the 0 migration is working great. Thank you for help and for making this library! Thanks for the suggestion carmas. I will probably use that method for future migrations. As far as I'm concerned this issue is closed.

cmbarnett87 commented 8 years ago

@moweber I'm glad to see you got it to work! I saw your SO post too and thought the posted response wasn't helpful. I've been trying to do a very similar task where I want to populate a table with data the first time (ever) the user starts the app. Any chance you could post part of your migration script?

moworld commented 8 years ago

Sorry, I thought I posted this already. The project is on github @ daweber/Brackets. Here is a direct link to the Migration class:

DatabaseInit