MongoDB with Async Python Transcripts
Chapter: Beanie Quickstart
Lecture: Beanie Quickstart: Part 4 Queries
Login or
purchase this course
to watch this video and the rest of the course contents.
0:00
Carrying on, let's go to talk about queries and how we can do queries from our database.
0:09
So again, copying three to four this time, let's go up to the main and really I would have preferred to talk about queries first and then inserts.
0:17
But guess what, without data, super boring, super boring to run queries against nothing.
0:23
So we're going to write another async function about getting some users back from the database
0:28
and even making changes and saving those changes back into the database with Beanie.
0:32
So I'll call it find some users, but it's really find and update some users. Again, I'll have to be an async function here.
0:41
And kind of hinted at this a little bit previously when we talked about the class methods.
0:46
So if we want to do a query, we can come in here and let's say we want to find all the users of a particular country.
0:54
say the users are and we go to the class the type. And here we can say, find, find one
1:01
find all which really awesome about beanie is it lets us program against this query system
1:07
by build these queries, actually using the types that Python knows and understands. So
1:12
things like refactoring work and type checking work. So what we do is we want to find let's
1:17
say we want to find all the users in the USA, and the users in the USA, we're going to update
1:23
their password. So we're gonna go user dot location dot country, equal equal, right,
1:32
that's how you do it in Python, equal equal, USA, MongoDB is case sensitive, as I said
1:38
before, so be really, really careful. So there's multiple ways in which we can get ahold of
1:44
these users. And I'll just write two queries here for them. So we're gonna get the users
1:48
back. Now maybe we want to have them sorted in some way like by their name. So we can
1:53
say sort user dot name, not dunder name, but just name. And in this all at once mode, what
2:01
I want back is I want a list of users. So over here, I want to basically have the type
2:05
be list of user. In order to do that, we have to say to list. Now, so far, this has just
2:15
been a cursor type thing, it returns a query fluently. But now this to list, this is a
2:21
coroutine. In order to get the results and execute the coroutine, you guessed it, we're
2:27
going to await that result. So for a moment, let's just print users just to see what happens.
2:32
All right, let's print them out. Now, remember to run the right one. There we go. We have
2:39
a user with their object ID, Michael, countries USA, and another one. And we could do it like
2:48
this make it a little more obvious. You can see Michael, Michael and Sarah. Remember,
2:56
Michael kind of got inserted twice from the created user and then the insert many but
3:00
whatever, it's fine. See, we got the right one. And look at the order, we got them, Michael,
3:06
Michael, Sarah, we want them in the other order. There's a couple of options here for
3:10
the sort, we can put a negative sign right here. When we run this, and you get Sarah,
3:17
Michael Michael. Unfortunately, you also get a warning here that this isn't going to work.
3:24
We can suppress that for the statement if you want. Or you can put negative name in
3:31
a string without the user. Just negative name and that will also work. So not a huge fan
3:37
that that comes up as an error, but still, it's pretty awesome. Pretty cool way to program
3:43
against it. So this is one way this gives us all of the users. And let's do another one, where we
3:50
just have an iterable something that we can loop over. So we'll say users again. And this time,
3:56
we're not going to immediately awaited. So imagine there were 10,000 users. Well, do we want to put
4:04
all of them back into memory at the same time and then start working on them? Probably no, maybe,
4:10
but maybe not. So instead, what we're going to do is we're going to create this, let's call it a
4:15
user query just so we can have a slightly different name here. And instead, what we can do is loop
4:21
over and loop over it in your mind may seem like for you and user query. Do something with the
4:30
user, right? However, this is not your regular query. This is an async query. So here's a language construct you may not have run into before.
4:42
I need to asynchronously work with this query object to start pulling back and awaiting as we're working with talking to this cursor
4:52
every time through the loop. So what we can do is we can do an async for. Notice the arrow went away. And now there's our objects printed back
5:01
again. Very, very cool. So the last thing to do I want to make some changes to this object.
5:08
Instead of printing it, we've decided that everyone in the US, they've got the most awesome password.
5:14
It's going to be just the letter A. Okay, the hash of your password is. We're going to update those. Now this doesn't do anything in the database.
5:23
This changes the objects in memory. But something like that will. that will actually go and push those changes back to the database.
5:35
Then down here we could just print upgraded security for all USA users. Let's go over here and first look and see that. Here's Sarah from the US
5:48
and her password hash is null. Run it again. Upgraded the security for all USA users. We refresh our results here.
6:00
Let's go to a JSON view because why wouldn't you? And then you can see when it's USA, your password hash is A. When it's USA, your password hash is A.
6:13
Same thing here. But if you live in Baden-Württemberg, to which land your password hash was not updated. That's how it works.
6:22
We go and we write our queries. The same thing would have happened if we had just used this list here that we got back in memory and looped over it
6:30
and called save on each of them. But this is a little bit better if you wanna stream the results out of the database.
6:35
So you can either call one of these dot, we could do like a first or none, or we could, well, it would just give us one or none
6:44
if there was no matching ones, or we could get the whole list. Those are all directly executing. Or we could come up with the query
6:51
and then asynchronously iterate over the cursor to start processing the results. Now maybe you want to run an and type of clause here.
6:59
Maybe we could do it like, start to wrap this around so we can see a little bit better. You could do multiple finds, like so.
7:14
Just print out the names here. So here you can see Sarah is now gone and we just have Michael because Michael is the only character
7:27
that is both in the US and has the name Michael. Pretty cool, I guess if we even had a German Michael, they wouldn't show up.
7:35
We can't, it would be left out because of that clause. So this is an and, or we could do it like this, doesn't really matter. Same result.
7:43
We can either pass multiple restrictions, multiple filters to the find query, or we can have multiple find clauses pile up on the query itself.
7:54
In the end, the same thing goes over to MongoDB, so not really a big difference there. When we talked about the native query API,
8:01
we also saw that there were things like limit and skip for paging. So again, all of these things are here. So limit, let's say five, let's do paging,
8:11
let's say dot skip, three times five. What this would do is say, we're going to get the fourth page, zero-based,
8:22
fourth page of five results and just go get the next five and show them.
8:26
Now that doesn't make any sense because we only have two results, so it's going to be empty, but all those things are still available here.
8:33
Almost all the queries in native Mongo have some Python equivalent over on the side. We'll see more of them as we get into the PyPI data modeling.