How to select rows where a column is Null in SQLAlchemy

Updated: January 3, 2024 By: Guest Contributor Post a comment

Introduction

In database operations, filtering records based on null (or non-existent) values is a common task. SQLAlchemy, being a popular SQL toolkit and object-relational mapper (ORM) for Python, provides an innovative way to perform such operations. This tutorial will take you through different methods of selecting rows where a column has null values using SQLAlchemy.

Basic Querying with is_() Method

To begin selecting rows where a column is null, we use the is_() method provided by SQLAlchemy. It’s the most straightforward way to check for null values in a column:

from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String, select
from sqlalchemy.orm import sessionmaker

# Connect to the database
engine = create_engine('sqlite:///example.db')
Session = sessionmaker(bind=engine)
session = Session()

# Define a sample table
metadata = MetaData()
users_table = Table('users', metadata,
                  Column('id', Integer, primary_key=True),
                  Column('name', String),
                  Column('email', String)
                 )
metadata.create_all(engine)

# Basic query selecting rows with null email
stmt = select([users_table]).where(users_table.c.email.is_(None))
for user in session.execute(stmt):
    print(user)

This example demonstrates how to set up a SQLAlchemy session, define a table, and execute a basic query to find rows where the ’email’ column is null.

Using == None Effectively

Although using is_() is the most explicit way to check for null, SQLAlchemy also overrides the double equals operator (==) to provide similar functionality:

# Query selecting rows with null email using == None
stmt = select([users_table]).where(users_table.c.email == None)
for user in session.execute(stmt):
    print(user)

Be aware that using == None is SQLAlchemy’s internal sugar, and directly translates to an IS NULL SQL expression, which may not be the case in plain Python code where == None checks for identity.

Chaining Multiple Conditions

# Query with multiple conditions
stmt = select([users_table])\
          .where(users_table.c.email.is_(None))\
          .where(users_table.c.name.is_not(None))
results = session.execute(stmt)
for user in results:
    print(user)

When you need to filter by multiple columns, SQLAlchemy allows chaining. In the above code, the query filters out users who don’t have emails but have names specified.

Advanced Joins with Null Checks

Checking for null values in a table that joins with other tables is a more complex but common scenario. Here’s an example of a left outer join operation with a null check:

from sqlalchemy.orm import relationship

# Assuming 'orders_table' with foreign key 'user_id'
# and a relationship on 'users_table' to 'orders_table'

# Left outer join query with null check
stmt = select(users_table).\
          outerjoin(orders_table).\
          where(orders_table.c.id.is_(None))

for user in session.execute(stmt):
    print(user)

The outer join will include all rows from ‘users_table’ and matched rows from ‘orders_table’, and where no match is found, ‘orders_table’ fields are set to null. The is_() method is then used to check those null relations.

Conclusion

Throughout this tutorial, we’ve seen how to select rows with null values in one or more columns using SQLAlchemy’s syntactic conveniences, ranging from simple is_() checks, utilizing == None, through chaining conditions and utilizing null checks in more sophisticated join operations. Mastery of these techniques is key to crafting efficient database queries and managing data effectively.