Understanding Room migrations in Android

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everybody and welcome back thanks for tuning in to another episode in this series here uh my name is dominic and i am the host of the android factory in the last episode i kind of took a step back from coding and reflected on what we've built so far uh specifically i kind of talked about my encounter with the application and you know my initial thoughts on using it when i went to trader joe's with the first time as this or using this as my shopping list instead of whatever system we had before that which was normally pen and paper so if you missed that feel free to just jump on back and check out what i had to say and drop any notes that you have so far if you have any and in today's episode we're going to go ahead and kind of fill out something that i have been formulating in my head for a little while the idea of adding categories to each of these items and i'm not talking about these little priority levels essentially but instead uh you know toilet paper uh bread or i think in the last example here we use you know bananas and three-quarter inch nails um you know it could be very weird to see these next to one another but if you knew that this was something that you needed to get from your grocery shopping and this was something you needed to get from your hardware store you know we can kind of have that category associated with it and display that somehow in the ui so the user has a very clear indication of which category they would like to attach each of their items to i could imagine we'll get rid of this but i could imagine the uh category somehow existing in here and we will basically build another table that has all of our categories in it we will query that table and display them here for the user to select or when they are editing one they can maybe you know choose a different category to select and then um you know we will update the element accordingly so if we go ahead and just take a look at our item entity here we have um our entity our primary key and one of the fields we have in our object here is the category id so we can basically make this our foreign key that points to a primary key on another table and so if you're not familiar with how relational databases work it's pretty much exactly that you know you have two independent tables from one another and some element on let's say table a you have table and table b some element on table a is the indicator of the primary key for an element on table b so that there is a unique way to map elements from table a to uh join them with the elements on table b and then you can you know put those two together uh and then formulate your final you know entity that you're looking for here so we're going to go ahead and create another entity called the category entity this is going to be a data class i don't think we need those uh we're going to do at primary key um we'll just call this id uh and that will be a string excuse me a string and then also the name which will be a string so um we can copy this over i wonder if this will give us huh so it's not freaking out at the moment but we are going to change the um the table name here to have our category uh prefix there and then well that's basically all we need to do to annotate this class to become uh a table in our database so what we actually do is go ahead and update the abstract class here that extends the room database called app database we're actually going to go ahead and update the version here and so this is critical you have to update the version anytime you make a change to a table or anytime you uh make a change to the database and in this case we're actually going to be adding a new table here so uh in addition to the item entities class we have in our entities array we are also going to add in the category entity class and so now the version 2 of our database has both of these entities which will translate into tables in our database for us then we're also going to have to go ahead and create the [Music] category entity down and then we're going to go ahead and just change that to be the category entity down let's see where is this one we're just going to go ahead and create a new interface called category empty down we let's at least take well i mean honestly we just need to take all of this we want basically the same functionality but on a different table so we're going to go ahead and do that and instead of item entity we're going to have our category table and then instead of that we will take our category entity right so now we have since we renamed this a way to insert delete update our category entities and then we can actually get all of them as well so all these will be used in different fashions for some some way shape or form to basically allow the user to modify the database specific to the category entities so we will allow the users to add their own categories and assign those user created categories to the item entities themselves so let's uh let me see here let me just go ahead and run this really quickly we don't seem to have any dial class must be annotated with at dao of course sorry about that small syntax error that was a build time error not a um not an error that was coming up in our ide for us ahead of time and you saw the app load momentarily and then crash so here we have an illegal state exception it says a migration from one to two was required but not found please provide the necessary migration path via add migration or allow for destructive migrations via one of the room builder fallback migration methods so what does that mean what are you saying why are you showing me an error uh basically as we've updated this information here right we've changed the version from one to two and we've gone ahead and added this entity into our database so the app loads up and it previously had version one installed on it for for the database we then try to install a new basically update that version of the application to have a uh the same database with version two associated with it so as part of this migration pattern the system will ask room to migrate itself and there are two options that we have here and they call it out here in our um error case here you either need to provide a migration path or we need to invoke fall to destructive fallback to destructive migration uh in our database builder function here that we're calling and uh in that case it would basically nuke the database entirely and rebuild the database with these two tables completely fresh and so the obvious issue with that is if you had you know five ten 600 items in your database at that moment if we if we allowed the destructive migration to happen we would lose all those items in our database and so that would be very very poor for our for our users so you can see here there are a few different functions you can invoke the most basic is just the fallback to destructive migration this one i've never used before but it actually seems like you can specify when at some point you get to a certain version then you allow um destructive migrations but then also on a downgrade allowing for destructive uh migrations which is quite interesting i'm sure all of these have their uses and you know in some applications you can just completely wipe the database out because maybe you know you're gonna reload that database when the app loads up but in this case we're actually using it as a sense of storage for the users we really can't just destroy everything they have here so what we need to do is we need to add a migration here and we can add in a variety of them right it's a var arg parameter here so you can basically just add all the different migration objects that you want separated by a comma and so you can migrate from one to two from two to three from three to four et cetera and so you can actually provide instructions on how the database is supposed to migrate itself when we move from one version to the next here so that's exactly what we're going to do um let's say private val migration nope one to two is a migration oh well it's not a variable here we need to have a class integration extend our migration here what was this complaining about ah okay so we need the start version the end version so we're gonna do one to two and then we're gonna do control i and this is what i was looking for sorry it does not it should not uh can you make a private inner class yes you can very nice um so we have defined basically a basically a variable here the migration one to two and then we're going to go ahead and basically override this function migrate so the it is our responsibility at this point to take into account the previous version of the database and exactly what it uh the status it was in previously and then bring it to the status that it should be with whatever change we're making here so in this case we're going to go ahead and add a table to it so we basically need to leave everything else unaffected and add a table here to this uh within this migration so in all honesty i do not remember the syntax here so we're going to google this one add table migration android room [Music] um okay [Music] yeah it honestly might just be like that i was gonna say uh didn't think we had a better way to do this uh but this is actually a very nicely written answer here uh but essentially what we're going to have to do is run actual sql so this is getting a little bit more into the nitty-gritty here but it's uh very easy to either search around for this or learn this kind of stuff but if you're not familiar with sql uh it can be a little annoying so uh we're gonna have to create a table if not exists we have the category entity that's the name of our table and then it's going to have an id which is a string the primary key is id and then [Music] name is also a string okay so after a little bit more googling around here uh string is not the correct uh name of that uh data type it's actually text uh we're also gonna set this to not null we're gonna go ahead and add our name that's also not null and then at the end we specify what the primary key of the table is and so if we go ahead and just quickly look at this we see we have an id variable here we see we have a name variable here both of them are strings that are both non-null so we basically just need to reflect that in uh sql language essentially and so now at this point the application here should be able to migrate properly from one to two so if we go ahead and add our migration here [Music] okay can't be any of those um it just needs to be a regular class that's accessible and i guess that's actually a good thing if we ever get to testing this to make sure that it works we need this to be public so forget i did that from the beginning but we've had our migrate added migrations and we've migrated from one to two so if we go ahead and take a look at the let's see it doesn't see it yeah okay so um i can't get a snapshot of the database beforehand unless i go ahead and stash all this and i don't really want to do that so i'm going to go ahead and just run it again and at this point here we see the app boot up and we see everything returned to normal here no crashes no issues and i want to take a look at the database inspector at this point in time and if we do so we let things load a little bit very very nice we can see that our item entity table here as you can see here is has all the information that we would need everything seems to be unaffected at this moment in time and then our category entity table is completely empty but you can see that the id has this little icon next to it for primary key and this name variable as well and then a little table is empty note here so um i kind of forgot we needed to do this migration but i guess this episode turned into learning how to migrate your room database but that's basically it right so to recap you need to create the new entity for your uh that's basically going to define the schema and the structure of your table and then it's not necessary but you know we're going to go ahead and create our dao as well so that we can go ahead and interact with that table and then in the app database class you're going to have to go ahead and just modify whatever we need to here to notify the system of a change and in our case we had to add a new entity to the list of entities update our version and then provide a migration here because we don't want to lose all the users data if let's say we just had to add an item an element to the item entity itself like we just added a new field here we would have to then go ahead and basically do this exact same thing except instead of the sql statement creating a new table it would be modifying an existing table by adding or removing a particular column that is of you know whatever type data type it actually needs to be and so if we have to do that in some later date because of how we've uh you know some requirement that we run into we'll show i'll show you how to do that then but it's going to follow the same exact pattern here and kind of rinse and repeat anytime you need to do a migration to basically run some sql here on your the database that gets passed in here that is basically what sits under the hood behind the room so um in the next episode i think we're going to go ahead and actually now update our item entity to incorporate our category entity and then allow the user to uh or eventually allow the user to add categories to the application and then add those categories or assign those categories to a particular item entity and then we'll worry about displaying that information so a couple steps ahead of us for sure but hopefully you're interested in what's to come and i'm excited to build it for you so i will catch you in the next one see you then
Info
Channel: The Android Factory
Views: 479
Rating: undefined out of 5
Keywords: android, android development, android tutorial, android beginners guide, android kotlin, kotlin, android studio tutorial, 2021 android app, 2021 android tutorial, android navigation components, recycler view, constraint layout, single activity architecture, android jetpack, jetpack navigation, git, github, android viewbinding, epoxy, epoxyrecyclerview, Room, android database, dao, livedata, viewmodel, mvvm, room migration, android migration room, migrating database
Id: PXnhv93lYCI
Channel Id: undefined
Length: 18min 10sec (1090 seconds)
Published: Wed Mar 31 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.