Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

SQLAlchemy: Core Statements

00:00 In the previous lesson, you used SQLAlchemy to run raw SQL commands on your database. In this lesson, you’ll learn more about the core part of SQLAlchemy and use functions to achieve the same results. The next step is to move further into Python land and think even less about the SQL. Doing this, amongst other things, forces you to use parameterized calls, which if you’ll recall my rant in the previous lesson, is good for you but is also helpful in that you now get Python error messages when you mess up instead of the rather cryptic SQL equivalents.

00:36 The SQLAlchemy statements are still closely tied to SQL. Instead of doing SELECT with raw text, you’ll calling a .select() method. Let’s go into the REPL and play with some.

00:53 You start out the same as before, with an engine …

01:10 and a connection. And now this where different. SQLAlchemy can keep a representation of your database in its objects to make your easier. You get at this representation through the use of metadata objects. Let me just do an import.

01:35 And I’ve constructed a metadata object.

01:48 Wow, that was a lot of debug. Let me just scroll back here. I did this to grab info about the author_table. I did that by constructing a new Table object, passing the metadata object in, and using the autoload parameter, telling it to create the Table object based on the existing table.

02:07 That massive amount of log information is SQLAlchemy asking the database what it needs to know about the author_table so it can construct the metadata.

02:18 The Table object can be used to do other things, like create a new table, but in this case, the autoload is telling it to use an existing table to get the info.

02:28 I’ll use this moving forward in my queries. Let me scroll back down. And that’s what the author_table looks like. You can see info on each of the columns in the table being represented here.

02:44 Let’s use this to get some data. First off, I’ve imported a select statement.

03:05 And instead of using text and constructing a raw SQL statement, I’ve used the select object to structure a query. The select object takes a table object as an argument, and then the .where() method on it filters the query.

03:21 The .where() clause accepts any kind of Python comparison statement. SQLAlchemy knows how to translate these into the corresponding SQL. Note the use of the table object to filter on the first_name.

03:35 The .c attribute on the table object contains all of the columns on the table. This .where() clause is looking for all the Stephens in the first_name column of the author_table. I’m storing all of that inside of a stmt variable.

03:52 Not lot of info here, but if I print it out or convert it to a string, it shows the underlying SQL query that would get run. Like before, I call .execute() on the statement.

04:15 And that is my result set. As you can see, this is just another way of forming your SQL queries. The advantage here is that Python and SQLAlchemy are enforcing how you do that.

04:26 If you’re using a fancy IDE with type hints and auto-completion, that will help you even further. A SELECT without a WHERE clause automatically populates all the columns from the table in the query.

04:53 Alternatively, I can pass in the names of columns instead of the name of the table, in this case skipping the primary key in the result. You can compile these statements for efficiency and reuse.

05:15 Let me do that with this statement. And this is the query inside of the compiled statement. Notice that it used parameters for the WHERE clause.

05:35 You can examine the parameters that are attached to the compiled statement … And the results should be what you expected.

06:04 The WHERE clause is capable of taking multiple arguments to further refine your query. Of course, in this case, it resulted in the same output.

06:21 All right, how about adding some stuff? I’ve imported the insert method …

06:41 and the pattern is similar to the select. Create a statement, specifying the table being inserted into, and this time, instead of a WHERE clause, you have the attributes being inserted.

06:54 There’s the corresponding SQL … the compiled version, the parameters … and after I ran the insert(), doing a select() will show the new data.

07:22 Like with the raw equivalent, you can create multiple rows at a time.

07:46 Providing this list of dictionaries will create two new authors. Don’t forget all this is still inside a transaction. I should probably be committing more often.

08:07 And there’s the result. There are now seven authors in our database. You can probably guess where this is going.

08:36 Similar to before, I create a statement, specifying a .where() clause for my update and saying what the new values will be. Executed it … and Stephen’s name has changed. Rolling this back will put things back to where they were at my last commit.

09:09 See, undid the nickname. Not sure how Mr. King would feel about that. One more pattern for you: deleting things. Sing along with me. Import … statement …

09:35 execute. It’s like one of those follow-the-bouncing-ball things, but without the melody or music. And as the delete took effect, poor old Alex isn’t in our library anymore.

09:52 I’m going to roll it back. I like Alex.

10:05 And there you have it. I’m back to seven authors. That’s it for the core part of SQLAlchemy. Next up, I’ll show you the object-oriented way, using the ORM.

Become a Member to join the conversation.