Welcome! Whether you’re new to database programming or a seasoned pro, this guide will walk you through using SQLAlchemy to perform CRUD (Create, Read, Update, Delete) operations on an SQLite database using Python.
Working with SQLite across programming languages
- SQLite with NodeJS
- SQLite with Next.JS
- SQLite3 with Python
- SQLite with Python Flask
- SQLite with Python Django
- SQLite with Python AioSQLite
- SQLite with Python SQLAlchemy
- SQLite with Golang
- SQLite with Prisma
- SQLite with FastAPI
- SQLite with PHP
- SQLite for Expo Mobile Apps
- SQLite with React Native
- SQLite with PhoneGap
- OP-SQLite with React Native
- SQLite with C#
- SQLite with Javascript
- SQLite with R
- SQLite with Rust
Why SQLAlchemy?
SQLAlchemy is the leading ORM (Object Relational Mapper) for Python. It allows you to map Python classes and objects to database tables and rows to streamline database interactions. The key benefits SQLAlchemy provides include:
- Simplified SQL and database interaction from Python
- Abstraction of vendor-specific SQL dialects
- Powerful querying capabilities and expression language
- Connection pooling and transaction management
- And more!
By using SQLAlchemy, you don’t have to write raw SQL. The ORM translates your Python code into the appropriate SQL behind the scenes. This makes it easier to work with relational databases in Python without needing to be an SQL expert.
Getting Started
To follow along, you’ll need:
- Python 3
- SQLAlchemy installed (
pip install sqlalchemy
) - Access to a SQLite database (we’ll use in-memory SQLite for the examples)
I’ll also assume basic knowledge of Python and SQL databases. If you need a refresher, here’s a quick primer on SQLite data types to understand the examples.
Let’s dive in and see how SQLAlchemy makes CRUD so much easier!
Got it, here is an added installation section:
Installing Python SQLAlchemy
Before using SQLAlchemy, you’ll need to install it along with a Python DB API-compatible database driver.
For SQLite, first install SQLAlchemy:
pip3 install sqlalchemy
Then install the SQLite driver:
pip3 install sqlalchemy.dialects.sqlite
That’s it! These two packages are all you need to start using SQLAlchemy with SQLite.
The same overall process applies when installing SQLAlchemy for use with other databases like PostgreSQL, MySQL, SQL Server, and more. Just install the required dialect after the base sqlalchemy
package.
Now SQLAlchemy is ready to import and use for database access and ORM mappings!
import sqlalchemy
from sqlalchemy import create_engine
# ...
Creating a Table with SQLAlchemy
We’ll start by creating a basic users
table to demonstrate the CRUD operations. Here’s the code:
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('sqlite:///:memory:', echo=True)
Base = declarative_base()
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
name = Column(String)
fullname = Column(String)
nickname = Column(String)
def __repr__(self):
return f"<User(name={self.name}, fullname={self.fullname}>"
Base.metadata.create_all(bind=engine)
This creates a SQLite database in memory, defines a User
table with columns for id
, name
, fullname
, and nickname
, and uses SQLAlchemy’s declarative_base()
system to map it to a Python User
class.
The key things to note:
- The
User
class subclassesdeclarative_base()
to become a mapped ORM class - Each column maps to a SQLAlchemy
Column
with a data type - We can define custom methods like
__repr__
to change the display - Calling
create_all()
builds the table in the database
And that’s it! The table is now ready for us to use for the CRUD examples.
INSERT – Creating New Rows with SQLAlchemy
To insert new rows into the users
table, we start by creating User
objects and adding them to the session:
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
session = Session()
# Create objects
user1 = User(name='John', fullname='John Williams', nickname='johnny')
user2 = User(name='Susan', fullname='Susan Smith', nickname='suzy')
# Add to session
session.add(user1)
session.add(user2)
# Commit (required to write changes to database)
session.commit()
print(user1.id, user2.id)
This follows the basic SQLAlchemy workflow:
- Create a
Sessionmaker
to produce session instances - Instantiate
User
objects and populate their attributes - Add the objects to the session
- Commit to write the INSERT statements
After committing, the id
columns will be auto-generated primary key values from SQLite. Easy!
Of course, we can wrap this in a function to reuse the insert logic:
def insert_user(session, name, fullname, nickname):
user = User(name=name, fullname=fullname, nickname=nickname)
session.add(user)
session.commit()
return user
john = insert_user(session, 'John', 'John Williams', 'johnny')
print(john.id)
And there you have it – a reusable way to insert rows into the users table!
READ – Querying for Results with SQLAlchemy
SQLAlchemy provides extensive capabilities for querying database tables and retrieving results. Let’s run some basic queries on the users
table:
All Rows
To get all rows, just query the User
model:
users = session.query(User).all()
print(users)
This prints:
[<User(name=John, fullname=John Williams)>, <User(name=Susan, fullname=Susan Smith)>]
By Primary Key
Grab a single user by primary key using get()
:
user = session.query(User).get(1)
print(user)
Prints:
<User(name=John, fullname=John Williams)>
By Field Value
Filter by any column using SQLAlchemy’s flexible filtering system:
john = session.query(User).filter_by(name='John').first()
print(john)
Which prints:
<User(name=John, fullname=John Williams)>
We can filter across multiple columns, aggregate fields, join tables, sort result sets and much more. SQLAlchemy provides filter options for nearly any query need.
UPDATE – Modifying Rows with SQLAlchemy
Updating rows follows a similar workflow to inserting:
- Retrieve the object by primary key
- Modify attributes
- Commit to write updates
For example:
user = session.query(User).get(1)
user.nickname = 'JJ'
session.commit()
print(user.nickname)
This prints:
JJ
Just by updating the Python object attribute, SQLAlchemy handles translating that change into an UPDATE
statement behind the scenes on commit.
For extra reusability, we can add a custom update method to our User
class:
class User(Base):
#...
def update(self, name=None, fullname=None, nickname=None):
if name:
self.name = name
if fullname:
self.fullname = fullname
if nickname:
self.nickname = nickname
session.commit()
user = session.query(User).get(1)
user.update(nickname='John John')
print(user.nickname)
And we’ve built an update helper that abstracts away the save/commit logic!
DELETE – Removing Rows with SQLAlchemy
Finally, deleting rows uses the same pattern of fetching objects and removing:
user = session.query(User).get(1)
session.delete(user)
session.commit()
This issues a DELETE
statement for that particular object’s row.
And that covers the core CRUD operations with SQLAlchemy!
Wrap Up
I hope this tutorial gave you a great overview of how easy it is to implement full CRUD functionality with SQLAlchemy and SQLite. Here’s a quick recap:
- Create –
session.add()
,insert()
- Read-
session.query()
,get()
, filters - Update – Modify attributes and
commit()
- Delete –
session.delete()
andcommit()
With just these basic concepts, you can build rich Python applications on top of SQLite or any other SQL database supported by SQLAlchemy.
The key takeaways:
- SQLAlchemy provides a Python ORM layer to abstract SQL
- Database tables map to Python classes
- Insert, query, update and delete operations map to intuitive object operations
- Changes only write on commit()
To dive deeper, be sure to check out SQLAlchemy’s excellent documentation, along with the rest of my site for more SQL and data science tutorials!