Explain Codes LogoExplain Codes Logo

Selecting distinct column values in SQLAlchemy/Elixir

python
sqlalchemy
database-queries
distinct-values
Alex KataevbyAlex Kataev·Oct 7, 2024
TLDR

In SQLAlchemy, distinct() is the magic spell to get unique values from a column. Here's how to use it to get distinct name values from a User model:

# Must have the precious, the precious unique names! unique_names = [name[0] for name in session.query(User.name).distinct()]

By using distinct(), only unique name values will be selected - no repetitions, no confusion.

SQLAlchemy: Counting the unicorns... erm, unique values

Sometimes, it's not enough to know all the unique values, you also want to know how many there are. It's like counting unicorns in an enchanted forest, one could say. SQLAlchemy makes this easy like Sunday morning:

from sqlalchemy import func # Count the unicorns! I mean, unique names. count_unique_names = session.query(func.count(func.distinct(User.name))).scalar()

The combination of distinct() and count() returns the number of distinct names. Just as counting unicorns would tell you how many beauties are galloping around in your forest.

The Hitchhiker’s Guide to Efficient Queries

While listing distinct values, you might not need all the information Skyrim Dragonborn style. With options(load_only(*columns)) you can pick and choose:

from sqlalchemy.orm import load_only # Selecting the vital few, ignoring the trivial many minimal_data = session.query(User).options(load_only('name')).distinct()

This way, you only retrieve unique user names, improving query speed remarkably and saving yourself from information overload.

Extracting the juice… err, results

Once you've performed your distinct() query, you're not done. The next step is extracting the results. List comprehensions pull this off smoothly:

# Producing a no-nonsense list of unique names unique_names = [result.name for result in session.query(User.name).distinct()]

This way, you create a neat list of unique names, avoiding unnecessary tuples being sprinkled all over the place.

Applying filters with distinct

Sometimes, you need to apply filters along with fetching unique values. It's like looking for a needle in a haystack:

# Finding a needle, in a haystack of potions unique_strong_potions = session.query(Potion.name).filter(Potion.effect == 'Strength').distinct()

This query filters potions with a 'Strength' effect first, before distinct() retrieves only unique names.

Aggregating distinct values

Gaining insights from distinct values involves combining them, a bit like making a smoothie:

from sqlalchemy import func # Making a strength smoothie strongest_potion = session.query(func.max(Potion.strength)).filter(Potion.effect == 'Strength').scalar()

This query finds the strongest potion, the equivalent of a Hulk Smash among potions.

Ensuring accuracy of results

To trust the results, it's always a good idea to check the SQL query generated. It's a bit like checking your shopping list one last time before checkout:

query = session.query(User.name).distinct() print(query) # Want to know what the query really says? Here it is!

By printing the SQL query, you ensure the results are accurate. Sort of like double-checking your shopping list, minus the horrifying moment of realizing you forgot to buy cookies.