Flask SQLAlchemy ORM Basics
# CHAPTER 9
Flask SQLAlchemy ORM Basics
1. Introduction
In the previous chapter, we established a connection to the database. Now, we must define the structure of our data. Using SQLAlchemy, we don't write SQLCREATE TABLE commands. Instead, we define our database schemas using native Python Classes. In this chapter, we will build a User model, use the Python Interactive Shell to generate the physical database file, and execute basic queries to add and retrieve data.
2. Learning Objectives
By the end of this chapter, you will be able to:- Define database tables using Python Classes (Models).
- Map Python attributes to SQL Columns (Integer, String).
- Use the Python REPL (Interactive Shell) to execute code live.
-
Use
db.createall()to generate the SQLite database file.
-
Add records using
db.session.add().
3. Beginner-Friendly Explanation
Imagine you are the architect of a new library. You don't start by nailing wood together. You draw a Blueprint. You say, "Every Book must have an ID Number, a Title (text), and a Page Count (number)." In SQLAlchemy, a Model is that Blueprint. You write a Python class that describes exactly what a Book should look like. Once the blueprint is finished, you hand it to the construction crew (db.createall()), and they instantly build the physical wooden shelves (the SQLite Database File) to match your exact specifications.
4. Step 1: Defining a Model
Let's expand ourapp.py file to include a blueprint for a User.
*(Notice how the Python types db.Integer and db.String directly map to SQL data types).*
5. Step 2: Generating the Database
We wrote the blueprint, but the physicalapp.db file does not exist yet.
To build it, we will use the Python Interactive Shell (REPL). This allows us to run Python commands live inside our application's context.
Open your terminal, ensure (venv) is active, and start the Python shell:
Your prompt will change to >>>. Type the following commands exactly:
*Look at your project folder. You will magically see a new file called app.db appear! The tables have been created.*
6. Step 3: Creating Data (Insert)
Stay in the Python shell. Let's add users to the database.*(If you forget .commit(), the data is erased the moment you close the terminal).*
7. Step 4: Reading Data (Select)
Now let's ask SQLAlchemy to retrieve the data we just saved.*Type exit() and press Enter to leave the Python shell.*
8. Backend Workflow: The App Context
In Step 5, we ranapp.appcontext().push(). Why?
Because Flask is designed to handle multiple applications running simultaneously, the db object doesn't automatically know *which* application it is currently working with. The App Context acts as a spotlight, telling SQLAlchemy, "Focus your attention on this specific Flask app and its configuration right now." You will encounter App Context errors frequently if you try to run database commands outside of a routing function without pushing the context first.
9. Best Practices
-
Never Modify Live Tables with
createall(): Thedb.createall()command is great for creating a fresh database from scratch. However, if you add a new column to your Python Model next week, runningcreateall()again will NOT update the existing table. To safely alter existing tables, professional developers use a tool called Flask-Migrate (Alembic), which we will introduce in later advanced builds.
10. Common Mistakes
-
Forgetting
db.session.commit(): The most common beginner frustration. They rundb.session.add(user1), query the database, see the user, close the terminal, and the next day the user is gone.add()only places the data in temporary staging (RAM). It is not written to the hard drive until you callcommit().
11. Exercises
-
1.
What is the fundamental difference between
User.query.all()andUser.query.first()? What data type does each return (A list vs a single object)?
12. Coding Challenges
-
Challenge: Open the Python shell. Push the app context. Create a new User object with your own name and email. Add it to the session and commit it. Then, write a query using
.filterby()to retrieve your specific user from the database and print its email.
13. MCQs with Answers
In SQLAlchemy, what is the purpose of the db.session.commit() command?
When defining a database Model, which argument ensures that no two users can register with the exact same email address?
14. Interview Questions
-
Q: Explain the purpose of the "Database Session" (
db.session) in SQLAlchemy. Why does SQLAlchemy utilize a staging area rather than executing SQL inserts instantly upon object instantiation?
-
Q: What is the Flask "Application Context" (
app.app_context()), and why is it required when executing database operations via the interactive terminal shell?
15. FAQs
Q: Can I view theapp.db file visually like an Excel spreadsheet?
A: Yes! You can download free GUI tools like DB Browser for SQLite or DBeaver. You simply open the app.db file in the program, and it will display all your tables and rows in a beautiful, clickable interface.
16. Summary
In Chapter 9, we mapped our Python code directly to SQL architecture. We defined aUser blueprint using SQLAlchemy Model classes and configured column constraints like unique and nullable. Utilizing the Python Interactive Shell and the Flask App Context, we generated the physical SQLite database file. Finally, we executed basic CRUD operations, successfully staging and committing records to the database and querying them back out using Python syntax.