Building data-driven web apps with Flask and SQLAlchemy Transcripts
Chapter: MongoDB edition
Lecture: Concepts: MongoEngine and MongoDB
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 straightforward, we just pass
0:12 an alias and a name for the database and off it goes.
0:15 So here we said core and PyPI demo
0:17 and we call mongoengine.register_connection.
0:20 As long as our entities use the same alias
0:23 which is called db_alias
0:25 in their little meta data thing
0:26 as long as they use the same one
0:28 it just uses this connection, it's this ambient
0:30 way to get to the database so you don't have to go
0:32 through that session stuff.
0:34 The classes that we map to the database
0:37 derive from a built in base class, mongoengine.Document.
0:42 Everything that's going to be saved
0:43 to a top level collection is a mongoengine.Document.
0:46 Here we have a package, in this one
0:48 we're changing what the id is, like we did
0:51 we used a string instead of an auto incrementing id.
0:54 If we want to take a bson, auto generate a bson id
0:58 we could just omit that line but this one
1:00 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:06 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:13 and we have datetime fields, string field and so on
1:16 pretty straightforward.
1:18 What's really powerful though is that we don't have to limit
1:21 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
1:30 this takes other tables to manage
1:32 these many to many relationships.
1:33 Here we just have maintainers and we're just embedding
1:36 a list of items.
1:37 If we look at the record in the database
1:40 it looks like this, we have our id
1:42 the date, the summary and then we have a bunch
1:45 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 because it's many to many.
1:51 We're not embedding users in here right
1:54 but we can avoid that maintainers table
1:56 that is the normalization table.
1:58 If we want to do a simple query
1:59 so easy, just package.objects column equals value
2:03 for direct equal and then you want one
2:05 you say first, if you want to do all of 'em
2:06 you just iterate over it or you say .all().
2:09 Things like that.
2:10 So we're going to filter on one or more of the fields.
2:13 If you want to filter on more than one
2:14 and do an and and just comma separate
2:16 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 requests or SQLAlchemy.
2:24 We call first and this actually triggers
2:26 the execution of the query.
2:28 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 And 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 an 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
2:57 has an id, if we want to answer
2:59 the question of show me all of the bookings
3:01 for a given user or a given owner
3:04 we come through and say, go find that owner
3:06 it would do a simple query to get them
3:08 and then I can go to the room and say
3:11 go to the room's bookings, this double underscore
3:14 right there says navigate the hierarchy.
3:16 We have bookings, this is a list of guests
3:20 or something like that or an embedded singular object
3:23 called guests and it has a guest id.
3:26 So we're going into the bookings list
3:28 or embedded item, say go to the guest id
3:31 and then we want to do an inquiry which is a list of ids.
3:34 So show me the guest, find me all the bookings
3:37 who have a guest who is contained
3:38 within the owner's family ids.
3:40 Pretty awesome that we can do this
3:42 and the way you do it is the double underscores
3:44 both navigate hierarchies and they apply operators
3:47 like in, so double underscore in
3:49 that's the operator that's being applied in the query.
3:52 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 a prepared query
4:02 that's not actually executed and then if we run
4:04 into an error that error might happen
4:06 in a view model, even maybe in a template.
4:08 So my best practice for you is to make sure
4:11 all the data access is done by the time
4:14 you leave this function, in this case
4:15 a real easy way to do that is convert
4:17 this to an in-memory list, that means
4:19 the whole thing is accosted and we're not using
4:21 data access anymore, we're just now working in memory.