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.


Talk Python's Mastodon Michael Kennedy's Mastodon