Building Data-Driven Web Apps with Pyramid and SQLAlchemy Transcripts
Chapter: MongoDB edition
Lecture: Concepts: MongoEngine and MongoDB
Login or
purchase this course
to watch this video and the rest of the course contents.
0:00
Let's close out this chapter by reviewing
0:01
some of the concepts that we discussed
0:03
while going through our conversion
0:05
from SQLAlchemy to MongoDB.
0:07
First thing, we have to register connections
0:09
so pretty straight forward.
0:11
We just pass an alias in a name for
0:13
the database, and off it goes.
0:15
So here we said core, pypi_demo, and we
0:17
call MongoEngine.register_connection.
0:20
As long as our entities use the same alias
0:23
which is called db_alias in their little meta data thing
0:27
long as they use the same one, it just uses this connection.
0:29
Alright, it's kind of this ambient way to get to the database
0:32
so you don't have to go through that session stuff.
0:35
The classes that we map to the database derive from
0:38
a built-in base class mongoengine.Document.
0:42
Everything that's going to be saved to a
0:43
top level collection is a mongoengine.Document.
0:46
Here we have a package.
0:48
In this one, we're changing what the id is, like we did
0:51
we used the string instead of auto-incrementing id.
0:54
If we want to take a BSON, auto-generated BSON id
0:58
we can just omit that line
0:59
but this one we want to make sure it's a string
1:01
which is that unique, I guess we don't say unique here
1:04
we should say unique but that's a feature
1:07
but it's not one that we set.
1:08
Anyway, we want to make sure this is a unique thing
1:11
and that is just the name of the package.
1:14
And we have DatetimeField, StringField and so on.
1:16
Pretty straight forward.
1:18
What's really powerful though, is that we don't have to
1:20
limit ourselves to just tabular data.
1:23
We can have things like name, summary and homepage
1:25
that would be tabular, but then we can embed stuff.
1:28
Normally in a relational database, this takes other tables
1:31
to manage these many-to-many relationships.
1:33
Here we just have maintainers
1:35
and we're just embedding a list of items.
1:37
If we look at the record in the database
1:40
it looks like this.
1:41
We have our id, a date, the summary, and then we have
1:44
a bunch of maintainers that were put in there.
1:46
And this is just the id, this is like a relationship
1:49
back to the user table, cause it's many-to-many
1:51
we're not embedding users in here, right
1:54
but we can't avoid that maintainers table
1:56
that is the normalization table.
1:58
If you want to do a simple query, so easy.
2:00
Just package.objects(), column equals value
2:03
for direct equal, and you want one you say first()
2:05
if you want to do all of them, you just iterate over it
2:08
or you say .all(), things like that.
2:11
If you want to filter on one or more of the fields
2:13
if you want to filter on more than one and do an and
2:15
just comma separate them like any keyword arguments.
2:18
So in this case, the ID must match
2:19
the name of the past package name.
2:21
Like Request or SQLAlchemy.
2:24
We call first, and this actually triggers
2:26
the execution of the query.
2:29
If we didn't call that, we'd have to loop over it
2:31
or something, until then we could keep adding to it.
2:34
Now, it's going to return either one or None.
2:36
Let's imagine a world that we haven't been working in yet
2:40
that's a little bit more complicated.
2:41
We're doing a hotel, or Airbnb or something
2:44
and we have hotel rooms, those rooms have bookings
2:47
and the bookings store which guests are in them.
2:51
So we have a booking, object, it has an embedded object
2:55
called guest, that embedded guest object has an id.
2:58
If we want to answer the question of
3:00
show me all of the bookings for a given user
3:03
or given owner, we'd come through and say
3:05
go find that owner, going to do a simple query to get them
3:08
and then I can go to the room and say
3:10
go to the room's bookings, this double underscore
3:14
right there says, navigate the hierarchy.
3:17
We have bookings, a list of guests or something like that
3:22
or an embedded singular object called guest
3:24
and it has a guest id, so we're going into the
3:26
bookings list or embedded item.
3:29
So we go to the guest id, and then we want to do an
3:32
in query which is a list of IDs.
3:34
So find me all the bookings who have a guest
3:38
who is contained within the owners family IDs.
3:40
Pretty awesome that we can do this.
3:42
And the way you do it, is these double underscores
3:44
both navigate hierarchies, and they apply operators like
3:47
in, so __in, that's the operator
3:51
that's being applied in the query.
3:53
Now one of the patterns that I like to use
3:55
is make sure there's no data access outside this function.
3:59
We could return kind of a prepared query that's not
4:02
actually executed, and then if we run into an error
4:05
that error might happen in a view model
4:07
even maybe in a template.
4:08
So my sort of best practice for you is
4:11
to make sure all the data access is done
4:13
by the time you leave this function.
4:15
In this case a real easy way to do that is
4:16
convert this to an in-memory list.
4:19
That means the whole thing is exhausted
4:20
and we're not using data access anymore
4:22
we're just now working in memory.