Building Data-Driven Web Apps with Pyramid and SQLAlchemy Transcripts
Chapter: MongoDB edition
Lecture: Rewriting our queries
0:00 We saw our site doesn't work because we're trying to access SQLAlchemy which we're no longer configuring in our
0:08 various data services, so now what we're going to do is go rewrite these data services like this last latest releases.
0:15 It might sound challenging, but it turns out to be super easy, let's go do it. Here's part of that design pattern thing I spoke about.
0:21 We've taken every single bit of data access and we've isolated it down into just these two modules a couple of functions within each.
0:31 So that means, within the view models within the controller methods, all of that stuff none of them care about the details
0:39 of how we talk to the database they just expect classes back. And as long as the classes have the right type, it'll be okay.
0:45 So, that's the beauty right here. Let's go down, and all we have to do is rewrite these queries, rewrite how we get package count, for example.
0:54 So let's get to it, it's going to be really quick. We're going to change this to nosql. We don't use this unit of work pattern for MongoEngine.
1:02 I do kind of like the unit of work pattern but they don't use it, so here we go. Now instead of going and creating the query on a session
1:09 we go to the class and we say objects. Now this is just a blank query there's not filters and stuff, but we could put those here.
1:18 Okay, so that's going to do that one, let's do Release. This is going to do ... objects().count(). Okay, not too hard so far.
1:27 That's one's kind of the hardest one so let's put that away for a minute. So this one kind of looks complicated. Remember the joins and all that.
1:36 So we're going to find a package by name so we go to the package, and go to it's objects now we can .. the filter does work
1:42 exactly like this, but what we can do is if we're just doing one filter we can just put that ... right there. We don't need this filter statement.
1:50 OK, so it's kind of equivalent. The other thing that's different is we don't use double equal, we use single equal
1:56 and then we don't use the type, we just say the field. Okay, so it's just id is that. At this point, we can make this look a lot cleaner, like that.
2:03 That's pretty slick. Alright, we got one more down here. We want to go to create a list of the results of this query.
2:12 Objects and then we're going to get the limit by whatever that value is. Look at this, this is comin' along pretty easy, right?
2:20 Now, finally, this one here. So we want the releases ... Objects ... Order by ... Also exists in MongoEngine, but this syntax doesn't exist.
2:32 If you want to sort by this field descending, you just put it as a string with a minus in the string.
2:39 I don't like that as much, but that's how it works. That's it, this one's done, and then down here, again we're going to go to our package
2:47 it's going to be .objects() and this one gets pretty interesting. See how we're doing this query of I like the ID to be contained within this set?
2:57 Same idea in MongoDB, but it's going to go like this. Say id instead of dot, you do id__in to apply the operator and you don't have the ... there
3:07 and you just say equal the set. Different, not super hard. I think, I think this might do it. This may well do it. Let's run and see what happens.
3:15 Now we didn't change the user thing so that might, that might pose a problem, let's find out. None type is callable. Where is this?
3:23 Yep, user service, user count, okay. We got to do that over here. I think just the one, so, instead of data we'd have nosql, we don't have unit of work
3:33 we have .objects(). Let's try again. I think that might be enough to make it run. Boom, look at that, it's working! Like a champ.
3:43 If I login there's going to be some minor issues. We don't have our data yet, but it's great. We can even come over here and try to get to a project.
3:50 ike request, it's not in the database so it should 404, right? Perfect, didn't crash, it went to the database said eh, not here, 404.
3:58 Of course it's not here 'cause the database is empty. We're going to solve that problem in a minute but this, this is pretty awesome.
4:03 We now have our stuff converted. Let's go ahead and finish out this user stuff here. Turns out there's just a few steps left.
4:10 Okay, remember, create the user, all good. Instead of all of this, you just say user.save(). So here we're going to do a query
4:19 for the user by email, actually we have a little function below called find_user_by_email, let's just re-use that.
4:28 I think, it's going to do this as well. Alright, that's pretty easy. It's not, but it will now. So again, we don't do it this way
4:42 we go and say .objects() and we don't use the type name we do assignment like so. That's it. We have now entirely re-written our app.
4:53 100 percent, to move from SQLAlchemy to MongoDB using MongoEngine, period, done, that's all of it. And, most importantly, notice we've only changed
5:04 these two files that are focused on data access. Granted, we had to add these, because, well you can't have the entities without adding them
5:12 but it's not like we re-wrote a whole bunch of stuff up here. Notice, no color changes in this implementation.
5:18 Down in the view models, there's tons of them all over the place, no changes. Because we implemented this beautiful
5:26 little pattern of hiding our data access here, and then exchanging classes. Now, there's little tiny issues going on.
5:33 Like, let's see if we can find one, maybe this one. No, I was thinking maybe some of them import. pypi.data.user, and things like that
5:44 for, like type-ins, but they're not even doing that. If they did, we'd just change it I've chosen these to be exactly
5:50 at least really really close in terms of names of the columns and stuff, so that it really doesn't matter which one you say it is
5:58 but it's better to have it correct, of course. Almost works. There's one ultra small problem well, first, the data's not there
6:06 but there's one other small problem that we got to fix. It's going to require us to change the base ViewModel
6:11 so, this thing I told you about, the beauty there's one tiny detail, and the detail is because, over here, the user is using the default id
6:20 which is what's called an ObjectId whereas in this one, it's using an integer. The cookie handling needs to be slightly adjusted to deal with that.
6:31 No problem there.