Full Web Apps with FastAPI Transcripts
Chapter: async databases with SQLAlchemy
Lecture: Find user by id and email, async

Login or purchase this course to watch this video and the rest of the course contents.
0:00 Next up, let's rewrite these two, get_user_by_id and get_user_by_email here. So I'll comment this one out,
0:07 and it's gonna be quite similar to what we just did, which I copied. So we're gonna create this async session, then I'm gonna create
0:13 a query, but now the query, this one's a little bit more like what you would expect.
0:19 I'm gonna say, gonna create a select of user where we filter, I wanna filter by user, what are we doing, id, this time equals user_id.
0:27 Now previously what we did, as you can see right below is we did first(). So we're not gonna do that here.
0:33 The, we can't do those types of queries directly on the select statement, we do it on the results. We gotta come in here and get our result,
0:41 and then we're gonna say scalar_one_or_none. So give us the actual value, which in this case is gonna be a user object, the one that you got or return
0:52 None. Don't crash if there's no results, like if they pass the wrong id or in the case below, we're checking to see if it exists,
0:59 right? Or to say, give me this, Is there a user by this email? Yes or no? So we could also rewrite this one really quickly as well.
1:08 In this case, it's just email and email for our comparison here. And that should do it. Maybe format it like this. Make it look a little better.
1:18 All right, so this should do it. But in order for us to write this code, we have to make this async functions, right?
1:26 And then where they're called, we have to convert those things to async, right? It propagates up the stack. In this case, we got our AccountViewModel,
1:38 and it's gonna need one of these def load, which is an async function. Then here it says, warning,
1:44 you have not defined a user class in the globals object yet, right at the startup. So we want to make sure we always do that.
1:50 It's going to be an Optional[User], we don't know if there's one coming back or not. Initially, there won't be one. Now,
1:56 PyCharm should be complaining to us here, but it's not so if we go look, this is an async function and where we're calling it,
2:05 what we get back, as you saw is a coroutine. So we need to await this right there. Right, then up the stack. Where are we using this?
2:14 Well, we're using that in our view for account in the index right here. So we'll await vm.load(), which means this has to be async.
2:25 Now we're all the way to the top of the stack. Hand that off too FastAPI, and it'll go. Let's just see if this will work real quick.
2:32 So let me first log in, There's a problem, not gonna work, is it? It does work, look at that. We haven't changed that function yet.
2:41 So over here, we got Sarah Jones2, and we were able to log in. This is our slash account, which is running that code right, ups moved around, running
2:53 that code right there. Perfect. The other one that we were working on is this one right here. So we need to see where we're calling this.
3:05 We're just calling it in this one place where we're doing this check. And so this one is already async luckily, because we had to do that for the form.
3:12 So we're just gonna need to make sure we're awaiting this. So we wouldn't have been able to register because it would have said coroutine is
3:19 not none. So that means the email was taken, not actually true. Let's run this again and make sure we can register
3:25 now. I log out, register and register a third Sarah Jones. See if she can register. First let's try to register with her old self.
3:42 Nope, that email is taken. Oh, yeah, that's right. This is actually my email. Let's try that. Boom. Sarah Jones3 was able to register.
3:50 All right, So hopefully you're seeing the pattern here, right? What we do is deep, deep down in the service layers,
3:57 we switched to the async session objects, we await the database queries, that converts these methods to be async that just propagates
4:07 up the chain. So If we're over here, in the view model, we have to make sure that the load, we have some
4:13 function that we can make async where we're doing these calls. For example, this one already was. We had to make sure we added the await
4:20 right there to actually get the email back, not just the coroutine

Talk Python's Mastodon Michael Kennedy's Mastodon