SQLAlchemy is a powerful Object-Relational Mapping (ORM) library for Python that bridges the gap between database systems and Python code.
Instead of writing raw SQL queries, SQLAlchemy allows you to interact with your database using familiar Python objects and methods.
This tutorial will guide you through using the basic SQLAlchemy with SQLite to build a simple data-driven application step by step.
By the end of this tutorial, you'll understand how to:
- Set up a SQLAlchemy project with SQLite
- Define database models
- Perform CRUD operations (Create, Read, Update, Delete)
Prerequisites
Before starting this tutorial, ensure you have:
- Python 3.13 or newer installed
- Basic understanding of Python programming
- Familiarity with SQL concepts is helpful but not required
Step 1 — Setting up your SQLAlchemy project
In this section, you'll create your project directory structure, set up a Python virtual environment, and install SQLAlchemy.
First, create a directory for the project and navigate into it:
Next, create a Python virtual environment. This creates an isolated environment for installing packages:
Activate the virtual environment to start using it:
Now that your virtual environment is active, install SQLAlchemy using pip:
This installs the latest version of SQLAlchemy. You'll use SQLite as your database backend since it doesn't require a separate server installation and stores data in a single file, making it perfect for learning and small applications.
With SQLAlchemy installed, you're ready to create your first database connection.
Step 2 — Understanding SQLAlchemy components and creating your first model
In this section, you'll learn about the core components of SQLAlchemy and create your first database model. Understanding these components is essential for building practical database-driven applications with SQLAlchemy.
Before diving into code, let's understand the main components of SQLAlchemy:
- Engine: The core interface to the database, handling connections to a particular database server
- Session: Manages persistence operations (i.e., saving objects to the database)
- MetaData: A registry that tracks which tables exist for a particular database
- Declarative Base: A factory that creates a base class for our model definitions
- Models: Python classes that map to tables in our database
Let's create a basic script called database.py that sets up these components:
This script sets up the foundation for your SQLAlchemy database.
The create_engine function establishes a connection to an SQLite database named library.db. If the file doesn't exist, SQLite will automatically create it. The echo=True parameter enables SQL logging, which helps you see the generated SQL queries.
The Base class, created using declarative_base(), serves as the parent class for all your database models. Any model you define will inherit from this class, allowing SQLAlchemy to map Python classes to database tables.
Finally, SessionLocal is a factory function that creates session instances. These sessions allow you to interact with the database by executing queries, inserting records, and managing transactions efficiently.
For this tutorial, you'll build a simple library management system. Let's now start by defining a model for books.
Create a file called models.py:
This code defines a Book class that maps to a 'books' table in the database.
The __tablename__ attribute specifies the table name.
Several columns are defined with different data types:
id: A primary key that auto-increments.title: A string field that cannot be null (nullable=False).author: A string field that cannot be null (nullable=False).pages: An integer representing the number of pages.publication_date: A date field.price: A floating-point number representing the book's price.
When printed, the __repr__ method provides a string representation of Book objects, making inspecting them in the console easier.
Now, let's create our database tables. Create a file called create_tables.py:
Run this script to create the tables:
You should see output similar to:
From this output, you can see that SQLAlchemy first checks whether the books table already exists by executing PRAGMA main.table_info("books").
Since the table does not exist, it generates and runs a CREATE TABLE statement. This statement defines all the specified columns and their respective data types and constraints.
Once the table creation is complete, the transaction is committed to finalize the changes.
At this point, the library.db file is created in your project directory, containing an empty 'books' table, ready for storing book records.
Step 3 — Adding data to your database
In this section, you'll learn how to insert records into your SQLite database using SQLAlchemy's ORM approach. You'll create book objects, add them to the database, and see how SQLAlchemy handles the conversion between Python objects and database records.
Now that your database structure is set up with the Book model, let's add some data. Create a file called add_books.py:
First, you created a session using SessionLocal from database.py, establishing a connection to the database. Then, you defined a list of Book objects, each containing a title, author, page count, publication date, and price.
Next, you added all the books to the session with session.add_all(books), marking them for insertion. You committed the transaction using session.commit(), which executed the SQL INSERT statements. After committing, you retrieved and printed each book’s auto-generated id.
Finally, you closed the session with session.close() to release the database connection.
Run this script to add some data:
You should see output like:
In the output, you can see the SQL statements that SQLAlchemy generates and executes. Each book generates an INSERT statement with the appropriate values.
With these books in your database, you can query them in the next step.
Step 4 — Querying data from your database
In this section, you'll learn how to retrieve data from your SQLite database using SQLAlchemy's query API.
Now that you have some books in your database, let's write queries to retrieve them. Create a file called query_books.py:
The session.query(Book).all() method retrieves all books from the database as a list of Book objects. You can then access any attribute of these objects, such as title, author, and price.
Run this script to see all the books in your database:
You should see output like:
From the output, you can see that SQLAlchemy executes a SELECT query to fetch all books from the database. It retrieves the book details and displays them in a readable format.
Often, you'll want to retrieve only records that match certain criteria. Here's how to filter data:
The filter() method lets you specify conditions for your query, similar to SQL's WHERE clause.
You can also specify the order of returned records using order_by():
If you only need one record, you can use first() instead of all():
These query methods form the foundation of retrieving data with SQLAlchemy. Remember to always close your session to release database resources when you're done with it.
In the next step, you'll learn how to update existing records in your database.
Step 5 — Updating records in your database
In this section, you'll learn how to modify existing records in your SQLite database using SQLAlchemy. After retrieving objects from the database, you can update their attributes and save the changes back to the database.
The most common approach for updating data with SQLAlchemy is to query for a record, modify its attributes, and then commit the changes. Create a file called update_books.py:
First, you query the database to find the book you want to update using filter() and first(). Then you modify the book's attributes directly, in this case changing its price. Finally, you commit the transaction with session.commit(), which sends the UPDATE statement to the database.
Run this script:
You should see output like:
This approach of modifying objects and letting SQLAlchemy handle the SQL generation is intuitive and powerful. You can update multiple attributes simultaneously, and SQLAlchemy will generate the appropriate UPDATE statement.
You can modify multiple attributes of an object before committing:
SQLAlchemy will generate a single UPDATE statement that changes all modified attributes.
In addition to that, you can update records based on conditions:
For scenarios where you need to update multiple records that match certain criteria, you can use the update() method on the query object:
This approach is more efficient for bulk updates because it executes a single SQL UPDATE statement rather than retrieving each object individually. The synchronize_session=False parameter tells SQLAlchemy not to update the objects in the current session, which is more efficient for bulk operations.
Now that you can update records in the database, it's time to learn how to delete them.
Step 6 — Deleting records from your database
In this section, you'll remove records from your SQLite database using SQLAlchemy. You'll see how to delete individual records and how to perform bulk deletions based on specific criteria.
The most common approach for deleting records is to retrieve the object first and then use the session.delete() method. Create a file called delete_books.py:
In this script, you first check how many books you have by using query(Book).count(). Then you find the specific book to remove with filter() and first().
Once found, you mark it for deletion with session.delete() and actually perform the deletion by calling session.commit().
To confirm the deletion worked, you count the books again and list the remaining ones to see that "To Kill a Mockingbird" is no longer in the database.
Run this script:
You should see output like:
You can also delete records by primary key if you know it:
For cases where you need to delete multiple records that match certain criteria without retrieving them first, you can use the query's delete() method:
This method is more efficient than fetching objects and deleting them individually, especially when dealing with large numbers of records, because it executes a single DELETE statement with a WHERE clause instead of multiple statements.
With this, you now have a solid understanding of the basic CRUD operations with SQLAlchemy.
Final thoughts
This tutorial walked you through SQLAlchemy's essential features—connecting to databases, defining models, and performing CRUD operations with SQLite. You now have the fundamentals to build data-driven Python applications.
With the foundation you've built, you can now explore more advanced features like relationships between tables, migrations with Alembic, and optimizing queries for performance. For more detailed information, check out the official SQLAlchemy documentation.