MongoDB with Async Python Transcripts
Chapter: Beanie Quickstart
Lecture: Beanie Quickstart: Part 2 Connections

Login or purchase this course to watch this video and the rest of the course contents.
0:00 We saw that connecting to the database is a requirement before we can even create one of these Beanie documents.
0:08 And that's to make sure that once you do, you're able to save it or make queries on it and so on.
0:13 Now, that's what we want to do in this step. So let's go over here. And this one we're going to call P2 for Part 2, Connections.
0:25 and make sure we run this one, otherwise there'll be some mysteries about why what we're writing is not happening. So what is the goal of this one?
0:35 This is to connect to MongoDB with Beanie, really with Motor, as we pointed out, but ultimately connect Beanie to MongoDB.
0:48 So we've got this part here, creating a new user, and now that we're starting to do more things,
0:53 So let's make this its own method, so Control + T, Extract Method, and this is going to be Create a User. All right.
1:03 And then before that we saw we really need to set up a connection. So let's go and create that function.
1:19 For this, the first thing that we're going to need is a database connection string.
1:24 You might be familiar with these from other servers, like Postgres or SQL Server, but also you might be familiar with MongoDB.
1:33 Call this a connection string. We need that to be an F string in a second.
1:38 It goes mongodb colon slash slash, so that's the scheme, localhost port 27017, the default MongoDB port.
1:48 Of course, if you've changed these or set up the server somewhere else, you'll want to make a change here as well.
1:54 And then we put slash the database name. So I'm going to put that as a variable, maybe we could even pass it over like this, DB name,
2:03 and say that that is a string. Alright, so up here, let's call this beanie quick start for the beanie quick start DB.
2:15 Once we have our connection string, we need to create a motor client. We'll say client equals motor, which we have to import.
2:27 What we really need to import is .motor_async_io. And from there we want to async_io motor_client like that.
2:41 And we'll just pass in the connection string here. And let's go ahead and just print out are we connected to the database.
2:48 I guess maybe do that the very, very last thing here. And now what we need to do is connect motor to Beanie. So we're going to say Beanie.initBeanie.
3:02 And what we need to do is set the database equal to the actual database object from this client.
3:08 bracket like a dictionary, DB name. The other thing we have to do is we have to
3:14 say what classes are being mapped over to this database. You could actually have multiple initialized sets of classes and one going to one database and
3:26 another going to another database. You might do that if one is logging and temporary and you don't really need to keep careful care of it or back it up
3:35 frequently, whereas you might have user data, you backup constantly or you store in different locations. So we need to say document models,
3:43 and into here we put a list, and what goes in the list? All the top level documents, not the embedded ones, just the top level one.
3:51 So we're gonna give it a list of user. Now PyCharm says, well, this is not exactly what we were looking for,
3:59 and that's because we need to put this back. Remember we disabled that just for a second so we could create one of these objects.
4:07 Now again, this is okay, great, a list of document classes, not just Pydantic models. All right, this looks like it should work.
4:15 It is not going to work. There's one final thing we need to do. And that is a consequence. This is actually the error.
4:24 This error trace malloc warning, what that means, it's a terrible error message. What it means is this actually returns a coroutine.
4:34 move it up a little. This returns a coroutine and it's async. So we need to await talking to the
4:41 database. Everything we do when we talk to the database is async, including initializing it.
4:47 So we want to write await. And in order to write await, we saw that this has to be an async
4:52 function. So where we call this, we now need to write await. In order to do that, this has to be
4:59 be an async function. And so finally, this call is just going to create the coroutine
5:05 and do nothing. Right? Nothing. So what we need to do, actually, you can see that error
5:11 message a little better if you scroll over coroutine main was never awaited. So we need
5:16 to as we saw before, asyncio dot run the top level async routine, let's import that.
5:26 Now, this all should work, we should be able to call this asynchronously, we're awaiting talking to the database.
5:33 And then this part where we create a user should no longer freak out saying it's not set up. Here we go. Look at that.
5:43 And notice there's two additional fields that we didn't see before the ID, that's the primary key and the revision ID.
5:50 Revision ID is for something called optimistic concurrency.
5:56 So if two parts of your application, or two users in a web app, something like that, concurrently,
6:03 pull up an object, they both pull it up, this one makes a change, saves it, this one made
6:08 a different change and saved it would overwrite that whole document.
6:13 So this revision ID says, Well, if you want to use it, when was this last changed, the
6:20 first one would make a change, save it back, find this one would say save it back where the revision ID matches my current revision ID.
6:27 And it would say, nope, can't do that because there's no such document with the original. It got incremented by the other user.
6:34 All right, so that's the optimistic concurrency story. That's what that's there for. Awesome.
6:40 So it looks like we connected to our database successfully. Let's just go open up Studio 3T here and see what we got. Not here yet.
6:50 So we've connected to it and if we make any interaction with it, it will show up, but we don't yet see our database.
6:58 So the final thing in our create the user, set up to do, just make sure set up the database connection before.
7:07 Let's go ahead and print the user in two places. Now we want to save the user, so there's a nice save and this will insert it if it's
7:17 new record, like the ID is none, or it'll update it if the ID exists, right, if it's already come out of the database.
7:27 Again, every time we interact with the database, this is a coroutine, so we have to await it.
7:37 And that means we need this to become an async method, which means up here we have to again await it. Perfect. Try again. Look at this.
7:46 Created a new user. Before the save, ID was none and revision ID was none. And then the name, email, and so on.
7:59 The object ID is now set by MongoDB when we did that insert. We're not doing anything with revision ID, but the rest of the values are the same.
8:08 Very cool. Do we have our user saved in the database? Let's see.
8:13 here, we will refresh. First of all, do we even have a database? Oh, a beanie quickstart.
8:20 Let's open that up. We got this collection of users. And in here, what do we get? Look
8:25 at that. We've got our object ID set, we've got our created date set x through our default
8:33 method, save for the last login email, our embedded location object, Portland, Oregon, Michael for the name and password hash is null.
8:44 Excellent, excellent. Now if you run this code multiple times, because we're not setting the primary key,
8:51 we're going to run this and just get many, many Michaels in the database. So be aware that you can either clear out this database,
9:00 or I'll skip just ahead for just to make sure that we don't get extra duplicates in here.
9:07 here. So let's say this, we'll say if a weight user.count greater than zero, print, already
9:17 have a user. Let's try that. Oh, we already have a user. We could even update this a little
9:24 bit and say this is a variable, user count. We already have users, of course, it'll say
9:35 users when they're one, but you know, we're not going to worry about that. Already have one users. Excellent.
9:40 Very nice. This is how we connect to the database. We have to have, remember, everything we do with the database is async.
9:49 So we're going to go and create an async method that will let us initialize this connection. Create a connection string to your server.
9:56 Of course, there's many more settings that can go into that connection string. Username, password, replica rules,
10:03 as real server, SSL certificate details, many, many things, slash database name. And then we create an asyncio motor client
10:12 from the motor library with that connection string. We hand off the database object to Beanie as well as express which users are managed
10:23 by this particular connection to this database. Here we go. And then we can go do queries. Again, this is a real simple one.
10:30 We'll get into that better in a minute, as well as we can insert them by awaiting a user.save or something along those lines. Pretty cool.
10:41 Step two, connections all set.


Talk Python's Mastodon Michael Kennedy's Mastodon