Flask-SQLAlchemy helps you connect your Flask app to a database easily. It lets you work with databases using Python code instead of writing SQL queries.
Flask-SQLAlchemy setup
from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app)
Set SQLALCHEMY_DATABASE_URI to tell Flask where your database is.
Creating SQLAlchemy(app) links the database to your Flask app.
site.db in your project folder.app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:password@localhost/mydb'
db = SQLAlchemy(app)
This Flask app sets up a SQLite database named test.db. It defines a User table with an ID and username. It creates the table, adds one user named 'alice', saves it, and then prints the first user.
from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False) def __repr__(self): return f'<User {self.username}>' with app.app_context(): db.create_all() new_user = User(username='alice') db.session.add(new_user) db.session.commit() user = User.query.first() print(user)
Always set SQLALCHEMY_TRACK_MODIFICATIONS to False to avoid extra warnings.
Use app.app_context() when working with the database outside request handlers.
Remember to call db.create_all() once to create tables before adding data.
Flask-SQLAlchemy connects your Flask app to a database simply.
Configure the database URI and create a SQLAlchemy object linked to your app.
Define tables as Python classes and use the database session to add or query data.
Practice
Solution
Step 1: Understand Flask-SQLAlchemy role
Flask-SQLAlchemy is a tool that helps Flask apps talk to databases easily.Step 2: Compare with other options
Options B, C, and D relate to other Flask features, not database connection.Final Answer:
To connect the Flask app to a database and manage data easily -> Option BQuick Check:
Flask-SQLAlchemy = database connection [OK]
- Confusing Flask-SQLAlchemy with template engines
- Thinking it manages user sessions
- Assuming it serves static files
Solution
Step 1: Recall initialization pattern
The simplest and most common way is to pass the app directly to SQLAlchemy constructor: db = SQLAlchemy(app).Step 2: Check other options
db = SQLAlchemy() db.init_app(appp) uses undefined 'appp'. db = SQLAlchemy(appp) uses undefined 'appp'. db = SQLAlchemy(app=Flask()) creates a new Flask app, not the existing one.Final Answer:
db = SQLAlchemy(app) -> Option AQuick Check:
Direct app in constructor = db = SQLAlchemy(app) [OK]
- Trying to pass app as a keyword argument incorrectly
- Creating a new Flask app inside SQLAlchemy
- Forgetting to link SQLAlchemy to the app
print(user.name) output?
from flask_sqlalchemy import SQLAlchemy
from flask import Flask
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50))
with app.app_context():
db.create_all()
user = User(name='Alice')
db.session.add(user)
db.session.commit()
print(user.name)Solution
Step 1: Understand model and data insertion
The User model has a name field. We create a user with name 'Alice' and add it to the database.Step 2: Check what user.name holds after commit
After committing, the user object still has the name 'Alice' stored in its attribute.Final Answer:
Alice -> Option CQuick Check:
User.name after commit = 'Alice' [OK]
- Assuming user.name becomes None after commit
- Thinking print causes a database query error
- Confusing model attribute with database column name
from flask_sqlalchemy import SQLAlchemy
from flask import Flask
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
db = SQLAlchemy()
db.init_app(app)
class Product(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80))
product = Product(name='Book')
db.session.add(product)
db.session.commit()Solution
Step 1: Check app context usage
When using db.init_app(app), database operations must be inside app.app_context() to access app config.Step 2: Verify other parts
The URI is valid, __tablename__ is optional, and db = SQLAlchemy() with init_app is valid. The missing app context causes runtime error.Final Answer:
Missing app.app_context() when adding and committing -> Option AQuick Check:
Database ops need app context [OK]
- Ignoring app context requirement with init_app()
- Thinking __tablename__ is always required
- Confusing init_app() with passing app in constructor
Solution
Step 1: Set correct PostgreSQL URI
The URI must start with 'postgresql://' and include user, password, host, and database name.Step 2: Initialize SQLAlchemy properly
Using db = SQLAlchemy() then db.init_app(app) is a flexible pattern, especially for larger apps.Step 3: Check other options
Set app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:pass@localhost/dbname'; then db = SQLAlchemy(appp) uses undefined 'appp'; Set app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'; then db = SQLAlchemy(app) uses SQLite, not PostgreSQL; Set app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:pass@localhost/dbname'; then db = SQLAlchemy(); no init_app call misses init_app call, so db won't link to app.Final Answer:
Set app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:pass@localhost/dbname'; then db = SQLAlchemy(); db.init_app(app) -> Option DQuick Check:
PostgreSQL URI + init_app() = Set app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:pass@localhost/dbname'; then db = SQLAlchemy(); db.init_app(app) [OK]
- Using SQLite URI when PostgreSQL is needed
- Forgetting to call init_app() after creating db without app
- Passing app to SQLAlchemy but using wrong URI format
Ready to prove it?
Pass the test and this pattern moves unknown
