MongoDB for Developers with Python Transcripts
Chapter: Mapping classes to MongoDB with the ODM MongoEngine
Lecture: A parting glitch
0:01 Let's look at one final thing, I think it is not beautiful but knowing about it and expecting it is really, really important,
0:08 not in the beginning, but as you evolve your application, you'll end up with some funky complications.
0:14 I actually chose the cars that I wanted to update very, very carefully, let me run this again, if I list the cars, notice here in particular state
0:23 far away from this Ferrari F40 from 2005, there's only one of those, right, notice the id it's d15 and ends in 7e, if I try to list the cars again
0:32 there's that one but oh, it ends in ae, list the cars again— now it's ending in a1, what is up with that?
0:44 Just to be clear, the other ones are not changing, like 0f that's always the value, for the first one 0f,
0:52 there's not a problem with Mongo or anything like that, what is going on here is this car was inserted into the database
1:00 when we just had a little bit of our class to find here, remember in the beginning, we didn't have this default concept
1:07 when I first introduced it, and somewhere along the way after we had inserted a few cars, then we added this, let's look at Robomongo.
1:18 If you flip through here, you'll see almost all the cars have a vi number, vehicle id number, vehicle id number
1:25 except for that F40 from 2005, right at the top— none. Because when it was inserted, there was no definition for a vi number
1:35 what the heck was that thing anyway, how was it supposed to know that was not here yet but would eventually exist; so we can do a couple of things,
1:42 the reason you keep seeing this changing numbers is that there's a default value and basically it gets created every time
1:51 it comes back from the serialization layer, but it doesn't get set from the database because there is nothing to set it to,
1:58 so every time it goes back, it reruns that lambda and gets a new value and we're not saving it.
2:03 So basically what we need to do is we need to upgrade our documents, now sometimes like I said, this doesn't matter,
2:08 but this one where we kind of counted on a default value to be there, and then it wasn't, well that's unfortunate.
2:21 and apply that, that's one option, another option is let's go here and let's write make sure
2:26 we just below configure Mongo I'll say update_doc_versions, or something like this define that function here, and what we can do is something like this
2:38 it's not exactly in a work, but it'll give you the idea what we're after; so we'll say for car in car.objects so basically
2:45 let's look through everything in this collection and let's save it back, I'm going to run this, and let's list the cars and see if we solved it,
2:54 I really wish it wasn't at the top but there is, 19, 02 what's going on, well, it turns out that unless we somehow forcibly change this object
3:10 it's like hey, this object is not dirty and we don't need to push it in there. And say mark as changed, vi number and let's try it again—
3:27 here we go, so we told it that it changed sadly even though it generates a default value
3:33 it doesn't look back into the database which I guess would be super expensive, it just says hey someone changed this, right
3:40 it didn't really trigger that, it came from the databases none and then we set it,
3:44 so it doesn't know to push that through, so you have to do this little bit of a trick here
3:47 to say mark has changed, and PyCharm says you're not supposed to do that, let's just tell it hey, don't make me look bad,
3:56 we have to do this you understand it, right? Very well, okay, so now we've got this save back to the database,
4:02 we only want to run this the one time, right, we don't want to run at all the time, this is just like a one time upgrade of our documents
4:09 and if you have a 100 thousand records, probably fine, if you have a billion records this is not how you want to do it,
4:15 you want to do some kind of in place updater or something better, write the script, so let's run this again, and now we should see our car here,
4:24 this is the 2005 F40, you know what, it is time for new tires, let's service this puppy.
4:31 Now we come down here and say I don't know how much new tires are in Ferrari, but let's say they're 2000, new tires,
4:36 the customer is pretty happy they had the low profile ones they were looking for but they could have been like a certain kind, who knows, whatever.
4:44 Perfect, that worked, now if we list our cars again, you can see that this one that was basically, we couldn't get to
4:51 because its vin number kept changing is now fixed and that's because when we reran that we said hey, force of the default of the vin number in there,
5:02 notice that none of these other ones changed, it did write them back to the database, but it wrote them back
5:07 in exactly the way they were before, so nothing changed there, I'll just run it one more time, this second one is,
5:13 I'll just copy this and we can go pull it back in a second, so if we put this back one more time, and then we try to service this car
5:24 one dollar test service they were pretty thrilled with that here you can see the test service, okay. So the ids are not changing when we do this,
5:40 it's just if they're not there they are created. Alright, so if that seemed kind of annoying, I'm sure it was annoying,
5:47 but let's think how this would be in a relational database, what would have happened if this was a say SQLAlchemy or something to that effect,
5:56 or if this was some other thing, we would have a lot more trouble evolving from one to the next, right, so we wouldn't have the problem of
6:04 hey here's a car that doesn't have a vin number, because if we didn't actually go and manually changed the database
6:11 every time we added something here, when we added this we would have had to go back to the database
6:18 and do like a migration or data transformation SQL query to actually change and add this column, same thing for this,
6:24 but none of that was required, it was just this one case where we went back in time that we had to do a little bit of work here.
6:30 So, sometimes you still have these scripts you've got to run, sometimes you still have these changes, you got to do and consider the version history,
6:38 but it's much much less often than with relational databases where every little change requires a script
6:44 or it's just oops things are out of sync, bam we can no longer work, but I did want to point that out to you that look,
6:50 you're going to have to be really careful, some of the time. as these things evolve, how are you going to deal with the fact
6:55 that in the database there is this thing that has no vehicle id number. If we're using PyMongo, it would have just come up as none
7:03 or key error or something like that, it would have been a little more obvious but that's just one of the trade-offs you get with these ODMs.