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