MongoDB with Async Python Transcripts
Chapter: PyPI Beanie
Lecture: Creating the DB Models
Login or
purchase this course
to watch this video and the rest of the course contents.
0:00
So to create the Beanie models, which recall are really just Pydantic models with a couple of extras and a different base class,
0:09
we want to go and define that class. Now we could do this by hand, or we could come back to our friend JSON to Pydantic.
0:19
And we're just going to use this tool here because we want it to match exactly and it doesn't make that much sense for you to watch me go,
0:26
Oh, it was an underscore in the created date instead of no underscore, just the words together, things like that.
0:33
So what we're gonna do is we're gonna go to Studio 3T, grab the JSON representation and drop it over here and then convert it,
0:42
and then we'll actually do some editing on these classes. So step number one, get a rough representation to start with
0:48
so that we don't have to drudge through that. Let's go. Over here, notice we've got things that are actually not part of JSON.
0:58
We have this ISO date up here. This is great. We also, if you go, let's see another one, for example, object ID.
1:05
This is not a thing that is in regular JSON. So remember this JSON to Pydantic is not JSON to Beanie. It doesn't understand MongoDB things.
1:17
This is gonna say, this is a malformed JSON. So what we can do is we can come over here and say, customize the view to just show pure JSON,
1:26
which will help us with this. You can also just edit it by hand, it's not a huge deal. The other thing is, is we go through here,
1:33
you see there's multiple records. So let's just get one that we expect to be representative. So we'll just say limit one,
1:40
that way we can just come down here, Command + A, Command + C or Control + A, Control + C. Right, so this is gonna be the most complicated one,
1:48
this packages one. Let's put that in here first. Hello bar, goodbye bar. We give it a second and over here we've got our type.
1:57
So this model, this is actually what we're gonna call package, then this is our embedded piece here and then we have those, all right.
2:06
So I'm just gonna take these pieces, here's too many layers of scrolling and let's put that into a class.
2:16
Also notice that you can have it auto adjust your API, your names and so on there. If you're working with like a C# API or a JavaScript API
2:28
that has a different naming convention. Over to chapter eight, Beanie PyPI. I'm gonna make a folder here called models, lowercase models.
2:38
And that's where I'm gonna put these different classes. We could make a module called models, but I kinda wanna have it like this.
2:46
I really prefer, if you have taken my courses before, you'll know that I prefer to have one class per file
2:53
or really focused files and have more of them brought together. So that's what I'm doing. You do what you like. So this is gonna be Package, like that.
3:02
And we'll just do a paste. Now, notice I would rather type Pydantic for the moment here and import Pydantic.
3:13
Now, because Release is not a top-level object, it is actually an embedded object. Pydantic base model is the right type here.
3:25
This one is gonna be package and this is not gonna be a base model, right? It needs to be something that, for example,
3:32
brings in the queryability and the ID. So this is gonna be a Beanie document. And this docs URLs, a lot of times where we have any,
3:41
it's because it was null. So we want this to be optional, but it's not actually any, it's a string or it's optional.
3:48
Just because it's null, the Pydantic converter is like, you've given me no information, so this is what you get.
3:55
I'll say this is an optional of string. And let's go ahead and apply that to a couple. For example, this could be that way,
4:06
package URL, author name, especially the any. And this, in newer Python, we can use a lowercase list as of three,
4:15
and this is going to be a list of bson.objectId. That comes from MongoDB from PyMongo. And again, up here, this is going to be a dateTime.
4:26
We need to import that, datetime. That member datetimes, for whatever reason, don't exist in Java and JSON. So there's no way for it to know
4:36
that this could be a datetime, right? This is one of those bson upgrades, just like the objectId at the bottom here. And we have our list of release.
4:43
Okay, this is looking totally good again, int, int, int, create a date comment. This should be optional.
4:51
I think that's the only one that needs to be optional there. Excellent, so we've got everything working
4:57
for our most complicated part of our data model, the package and its nested embedded releases. Let's do the other two real quick
5:04
and we'll have these models put together. This one, we could do the limit one, But you know what? Not necessary.
5:15
Now again, notice it says invalid JSON for a second. Let's just turn that, tell them that's a string. So this is simple enough.
5:23
We could have typed it in ourself. This one, recall, was called release analytics. So we're just going to call the class name that as well. [no audio]
5:41
This should be a Beanie document. And it's going to be ReleaseAnalytics. The class, this we don't have to put here, right?
5:52
Explicitly this is handled by the base class, and this is an integer, so pretty simple, right? There it is. And finally, the last one we have is User.
6:02
Now, I know we modeled User again in the previous demos we've done, but I want to make sure it's an exact match, so let's just say limit 1.
6:12
And we'll just take this one, assume it's typical enough. Go in here. I'd use the simplified pure JSON view, so we'll take just that part there.
6:27
Again, this was null, so this is an optional.
6:44
But it's not just any, it's an optional string. Same there. And this is a beanie. The ID is done by itself, yes. It's called a user.
7:03
Email is fine. Hash password is going to be an optional string. Created date again is a date/time. This was a null. And this is a location.
7:18
Now, if maybe you weren't necessarily going to set a location, you could make this be
7:23
an optional location, but it looks like every record had it, so we're going to leave it like this here. And there it is.
7:29
We have our user with their embedded location. We have our package with its embedded release, and we have our release analytics because
7:39
we need to answer the question of how many packages there are, how many releases there are total, and that's just not something that we can simply do.
7:46
could do with the aggregation framework, but would it really be as fast as you want for something you might want to know all the time? Probably not.
7:55
So, we're just going to create this separate collection to store that little bit of data. And there it is.
8:02
Hopefully going through that process helped you a lot. I know it was a little bit repetitive perhaps, but going through it a couple times, showing
8:10
you how to actually bring all of that data over. We just did three collections. if you have a lot of different collections,
8:15
it's giving you a real clear roadmap and set of steps to make this happen in what I consider a pretty easy way.
8:22
There might be a mistake or two I haven't caught, hopefully not, like something that was specified as a string when it really should be an optional,
8:29
but we'll see about that. But I think we're pretty much there and we're ready to start doing some beanie with these models.