The basic setup: what you need before you start

To connect Flask to MySQL, you need three things: Flask itself, a Python library that speaks to MySQL, and a running MySQL server with a database already created. The most common library is Flask-SQLAlchemy, which handles the connection and lets you work with your data using Python objects instead of raw SQL.

Before you write any code, create your MySQL database and note down the username, password, host (usually localhost if MySQL is on your machine), and the database name. You will need these details in your Flask configuration.

Key Takeaways

  • Install Flask-SQLAlchemy with pip, then configure your Flask app with a database URI that includes your MySQL username, password, host, and database name.
  • The database URI follows the pattern mysql+pymysql://username:password@localhost/database_name, and goes into your Flask config as SQLALCHEMY_DATABASE_URI.
  • Create a SQLAlchemy object in your Flask app, then define your data as Python classes that inherit from the database model.
  • Use db.create_all() to build your tables, and db.session.add() and db.session.commit() to save data to MySQL.

Installing the required libraries

Open your terminal or command prompt and install Flask-SQLAlchemy and the MySQL driver. Run:

pip install Flask-SQLAlchemy pymysql

Flask-SQLAlchemy is the bridge between Flask and MySQL. PyMySQL is the driver that actually communicates with your MySQL server. Both are required; Flask-SQLAlchemy alone cannot connect without a driver underneath it.

Configuring your Flask app to find MySQL

In your Flask application file (usually app.py), import Flask and SQLAlchemy, then set up the connection string. Here is the structure:

from flask import Flaskfrom flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://username:password@localhost/your_database'db = SQLAlchemy(app)

Replace username with your MySQL username, password with your MySQL password, and your_database with the name of the database you created. If MySQL is running on a different machine or port, change localhost to that address and add the port number like localhost:3307.

The SQLALCHEMY_DATABASE_URI is the connection string. It tells Flask where to find MySQL and how to log in. The format mysql+pymysql:// at the start tells SQLAlchemy to use MySQL with the PyMySQL driver.

Defining your data as Python classes

In SQLAlchemy, each table in your database becomes a Python class. Each column becomes a class attribute. Here is an example of a simple users table:

class User(db.Model):  id = db.Column(db.Integer, primary_key=True)  username = db.Column(db.String(80), unique=True, nullable=False)  email = db.Column(db.String(120), unique=True, nullable=False)  def __repr__(self):    return f'<User {self.username}>'

The db.Model inheritance tells SQLAlchemy that this class represents a database table. db.Column defines each column: the data type (Integer, String, etc.), and constraints like primary_key=True or nullable=False. The __repr__ method is optional but useful for debugging — it controls how the object prints.

Creating tables in MySQL

Once your classes are defined, create the actual tables in MySQL. In a Python shell or in your Flask app, run:

with app.app_context():  db.create_all()

The app.app_context() is required because SQLAlchemy needs to know which Flask app it is working with. db.create_all() looks at all your model classes and builds the corresponding tables in MySQL if they do not already exist. If a table already exists, it does nothing.

Adding and retrieving data

To save a new record to MySQL, create an instance of your model class, add it to the session, and commit:

new_user = User(username='alice', email='alice@example.com')db.session.add(new_user)db.session.commit()

To retrieve data, query your table. For example, to get all users:

all_users = User.query.all()

To find a specific user by username:

user = User.query.filter_by(username='alice').first()

The session is a staging area for changes. You add objects to it, then commit() sends them to MySQL. query lets you retrieve data using Python syntax instead of writing SQL by hand.

Troubleshooting common connection problems

If you get an error like "Access denied for user", check that your username and password are correct in the connection string. If you see "Unknown database", verify that the database name exists in MySQL and is spelled correctly.

If Flask cannot find MySQL at all, make sure your MySQL server is actually running. On Windows, check Services. On Mac or Linux, you can test the connection from the command line with mysql -u username -p to confirm MySQL is listening.

If you get "No module named 'pymysql'", you skipped the pip install step. Run pip install pymysql again and verify it completed without errors.

Frequently Asked Questions

Can I use a different MySQL driver instead of PyMySQL?

Yes. mysqlconnector and PyMySQL are both common. Change the connection string from mysql+pymysql:// to mysql+mysqlconnector:// and install the corresponding package. The rest of your code stays the same.

What if I want to use an existing MySQL database instead of creating tables from Flask?

You can use flask-sqlacodegen to read your existing tables and generate the model classes automatically. Install it with pip, then run sqlacodegen mysql+pymysql://username:password@localhost/database_name to print the class definitions.

How do I update or delete records?

To update, retrieve the record, change its attributes, and commit: user = User.query.filter_by(username='alice').first(); user.email = 'newemail@example.com'; db.session.commit(). To delete, use db.session.delete(user); db.session.commit().

Do I need to close the database connection?

Flask-SQLAlchemy handles connection pooling automatically. In most cases you do not need to close connections manually. For long-running scripts outside of Flask, you can call db.engine.dispose() to close all pooled connections.

What does SQLALCHEMY_TRACK_MODIFICATIONS do?

This setting controls whether SQLAlchemy tracks changes to objects. Set it to False in your config to reduce memory overhead: app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False. You rarely need this feature in modern Flask apps.