Of course! Connecting to a MySQL database from Python on a Mac is a very common task. This guide will walk you through the entire process, from installation to writing your first Python script.

We'll cover the two most popular libraries:
mysql-connector-python: The official driver from Oracle. It's straightforward and reliable.SQLAlchemy: A powerful and popular Object-Relational Mapper (ORM). It's more abstract and makes working with databases much easier in larger applications.
Prerequisites
- Python 3: Make sure you have Python 3 installed. You can check by opening your Terminal and typing:
python3 --version
- MySQL Server: You need a MySQL server running. You can install it in a few ways:
- Recommended for macOS:
Homebrew. If you have Homebrew, installation is simple:brew install mysql
After installation, you'll need to start the MySQL service:
brew services start mysql
- Official MySQL Installer: Download the official DMG from the MySQL website. This gives you a graphical installer and the MySQL Workbench GUI tool.
- Docker: Run MySQL in a container. This is a great, isolated way to manage databases.
docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d -p 3306:3306 mysql:latest
- Recommended for macOS:
Step 1: Install the Python MySQL Library
Choose one of the libraries below. You only need to install one. Open your Terminal and use pip3 (the Python 3 package installer).
Option A: Install the Official Driver (mysql-connector-python)
This library gives you a direct, low-level connection to the database.

pip3 install mysql-connector-python
Option B: Install SQLAlchemy (The ORM)
SQLAlchemy uses a database driver (like mysql-connector-python) under the hood. When you install SQLAlchemy, it's best to also specify the driver you want it to use.
# Install SQLAlchemy and the MySQL driver together pip3 install "mysql-connector-python" sqlalchemy
Step 2: Get Your Database Connection Details
To connect, you need four pieces of information:
- Host: The address of your MySQL server. If it's on your local machine, this is usually
localhostor0.0.1. - User: Your MySQL username. The default administrative user is
root. - **Password`: The password for that user.
- Database: The name of the specific database you want to connect to.
You can create a database and a user using the MySQL command-line client:
# Connect to the MySQL server as root mysql -u root -p # Inside the MySQL shell: CREATE DATABASE my_app_db; CREATE USER 'my_app_user'@'localhost' IDENTIFIED BY 'a_very_strong_password'; GRANT ALL PRIVILEGES ON my_app_db.* TO 'my_app_user'@'localhost'; FLUSH PRIVILEGES; EXIT;
Now you have your connection details:

- Host:
localhost - User:
my_app_user - Password:
a_very_strong_password - Database:
my_app_db
Step 3: Write Python Code to Connect
Here are examples for both libraries. Create a Python file (e.g., db_test.py) and paste the code in.
Example 1: Using mysql-connector-python
This example shows how to connect, execute a query, and fetch the results.
import mysql.connector
from mysql.connector import Error
def get_connection():
"""Establishes a connection to the MySQL database."""
try:
connection = mysql.connector.connect(
host='localhost',
database='my_app_db',
user='my_app_user',
password='a_very_strong_password'
)
if connection.is_connected():
db_info = connection.get_server_info()
print(f"Successfully connected to MySQL Server version {db_info}")
cursor = connection.cursor()
cursor.execute("SELECT database();")
record = cursor.fetchone()
print(f"You're connected to database: {record[0]}")
return connection
except Error as e:
print(f"Error while connecting to MySQL: {e}")
return None
def main():
connection = get_connection()
if connection is None:
return
try:
# --- Create a table (DDL) ---
cursor = connection.cursor()
create_table_query = """
CREATE TABLE IF NOT EXISTS employees (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
position VARCHAR(100),
salary DECIMAL(10, 2)
)
"""
cursor.execute(create_table_query)
print("Table 'employees' created successfully.")
# --- Insert data (DML) ---
insert_query = "INSERT INTO employees (name, position, salary) VALUES (%s, %s, %s)"
employee_data = ('Alice', 'Software Engineer', 95000.00)
cursor.execute(insert_query, employee_data)
connection.commit() # IMPORTANT: Commit the transaction
print(f"{cursor.rowcount} record inserted.")
# --- Query data (DQL) ---
cursor.execute("SELECT id, name, position, salary FROM employees")
records = cursor.fetchall()
print("\n--- Employee Records ---")
for row in records:
print(f"ID: {row[0]}, Name: {row[1]}, Position: {row[2]}, Salary: {row[3]}")
except Error as e:
print(f"Error executing query: {e}")
finally:
if connection.is_connected():
cursor.close()
connection.close()
print("\nMySQL connection is closed.")
if __name__ == "__main__":
main()
Example 2: Using SQLAlchemy (Recommended)
This is often preferred because it handles the connection for you and provides a more Pythonic way to interact with the database.
import sqlalchemy
from sqlalchemy import create_engine, text
# IMPORTANT: The URL format is dialect+driver://user:password@host:port/database
# If your MySQL is running on the default port (3306), you can omit :3306
DATABASE_URL = "mysql+mysqlconnector://my_app_user:a_very_strong_password@localhost/my_app_db"
def main():
try:
# Create an engine, which is the core interface to the database
engine = create_engine(DATABASE_URL)
# 'engine.connect()' establishes a connection
# Using a 'with' statement ensures the connection is closed automatically
with engine.connect() as connection:
print("Successfully connected to the database using SQLAlchemy!")
# --- Create a table ---
# SQLAlchemy can execute raw SQL strings using the `text()` construct
create_table_stmt = text("""
CREATE TABLE IF NOT EXISTS products (
id INT AUTO_INCREMENT PRIMARY KEY,
product_name VARCHAR(255) NOT NULL,
price DECIMAL(10, 2)
)
""")
connection.execute(create_table_stmt)
connection.commit() # Commit DDL changes
print("Table 'products' created successfully.")
# --- Insert data ---
insert_stmt = text("INSERT INTO products (product_name, price) VALUES (:name, :price)")
connection.execute(insert_stmt, {"name": "Laptop", "price": 1200.50})
connection.execute(insert_stmt, {"name": "Mouse", "price": 25.00})
connection.commit()
print("2 product records inserted.")
# --- Query data ---
# The result of a query is a 'Result' object that you can iterate over
result = connection.execute(text("SELECT id, product_name, price FROM products"))
print("\n--- Product Records ---")
for row in result:
# You can access columns by index or by name
print(f"ID: {row[0]}, Name: {row.product_name}, Price: {row[2]}")
except sqlalchemy.exc.SQLAlchemyError as e:
print(f"An SQLAlchemy error occurred: {e}")
if __name__ == "__main__":
main()
Common Issues and Troubleshooting
-
mysql.connector.errors.InterfaceError: 2003: Can't connect to MySQL server on 'localhost:3306'- Cause: The MySQL server is not running.
- Solution: Start the server. If you used Homebrew:
brew services start mysql. If you used Docker:docker start my-mysql.
-
mysql.connector.errors.ProgrammingError: 1045 (28000): Access denied for user 'my_user'@'localhost' (using password: YES)- Cause: The username or password is incorrect.
- Solution: Double-check your credentials. You can reset the password for the
rootuser or your custom user using the MySQL command-line client.
-
ImportError: No module named 'mysql'orModuleNotFoundError: No module named 'sqlalchemy'- Cause: The Python library is not installed in the Python environment you are using.
- Solution: Make sure you are using
pip3(notpip, which might be for Python 2). You can also try installing it with the--userflag:pip3 install --user mysql-connector-python.
-
OSError: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)- Cause: This is a common socket connection issue. MySQL is trying to connect via a Unix socket file instead of TCP/IP on
localhost. - Solution: The easiest fix is to explicitly tell your Python script to use TCP/IP by changing the
hostfromlocalhostto0.0.1.# Change this: host='localhost' # To this: host='127.0.0.1'
- Cause: This is a common socket connection issue. MySQL is trying to connect via a Unix socket file instead of TCP/IP on
Best Practices
- Never hardcode credentials: Use environment variables or a configuration file (like a
.envfile with thepython-dotenvlibrary) to store your database credentials. - Always close connections: Use
try...finallyblocks orwithstatements (as shown in the SQLAlchemy example) to ensure database connections are always closed, even if an error occurs. - Use parameterized queries: Notice in the examples we used placeholders (
%sinmysql-connectorandnamein SQLAlchemy). This is the standard way to prevent SQL injection attacks. - Prefer SQLAlchemy for new projects: Unless you have a specific need for a direct, low-level driver, SQLAlchemy's ORM will save you a lot of time and make your code more robust and maintainable.
