Sling Academy
Home/SQLAlchemy/SQLAlchemy: How to Exclude Password from Results

SQLAlchemy: How to Exclude Password from Results

Last updated: January 03, 2024

Introduction

When fetching data using SQLAlchemy, it’s important to handle sensitive information like passwords carefully. This article shows various ways to exclude passwords from query results in SQLAlchemy.

Using Deferred Columns

Deferred column loading allows specific columns to be loaded only when accessed. Mark the password column as deferred:

from sqlalchemy.orm import deferred

# Define your User model

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    username = Column(String)
    email = Column(String)
    password = deferred(Column(String))

# Query without loading password
dummy_query = session.query(User).all()

for user in dummy_query:
    print(user.username)  # Password is not queried yet

Loading Columns on Demand

If you need the password in some cases but not others, load it on demand:

# Load password on demand
user_with_pass = session.query(User).options(undefer('password')).get(some_user_id)
print(user_with_pass.password)

Using load_only()

To explicitly tell SQLAlchemy which columns to load, use the load_only() function:

from sqlalchemy.orm import load_only

# Query only specific columns excluding the password
dummy_query = session.query(User).options(load_only('id', 'username', 'email')).all()

Directly Excluding Columns

It’s also possible to directly query all but the password column:

# Exclude password by not mentioning it
query = session.query(User.id, User.username, User.email).all()

Hybrid Properties for Security

Use SQLAlchemy’s hybrid properties to wrap the password in a computed attribute that doesn’t explicitly expose the password:

from sqlalchemy.ext.hybrid import hybrid_property

# Add a hybrid property that doesn't return the password

class User(Base):
    ...
    
    @hybrid_property
    def safe_data(self):
        return { 'id': self.id, 'username': self.username, 'email': self.email }

# Query and use safe_data instead of the row
dummy_query = session.query(User).all()
for user in dummy_query:
    print(user.safe_data)

Automating Exclusion

For a more advanced approach, override methods in the base class to exclude passwords by default:

class SafeQuery(Query):

    def instances(self, result, context):
        """Override the default instance creation method to exclude passwords"""
        return (self._safe_instance(row) for row in result)

    def _safe_instance(self, row):
        data = super().instances(row)
        del data['password']
        return data

Conclusion

In conclusion, SQLAlchemy provides various methods to exclude passwords or any sensitive information from query results. Use these techniques wisely to ensure that your application’s data remains secure.

Next Article: SQLAlchemy: Excluding Specific Columns from Query Results

Previous Article: SQLAlchemy: Serializing Query Results into JSON

Series: SQLAlchemy Tutorials: From Basic to Advanced

SQLAlchemy

You May Also Like

  • SQLAlchemy: Counting rows for each category (2 approaches)
  • SQLAlchemy: Adding a calculated column to SELECT query
  • SQLAlchemy: Grouping data on multiple columns
  • SQLAlchemy: How to temporarily delete a row
  • SQLAlchemy Composite Indexes: The Complete Guide
  • Full-Text Search in SQLAlchemy: The Ultimate Guide
  • SQLAlchemy: What if you don’t close database connections?
  • SQLAlchemy: How to Remove FOREIGN KEY Constraints (2 Ways)
  • SQLAlchemy: How to Create and Use Temporary Tables
  • SQLAlchemy: Saving Categories and Subcategories in the Same Table
  • SQLAlchemy: How to Automatically Delete Old Records
  • Weighted Random Selection in SQLAlchemy: An In-Depth Guide
  • SQLAlchemy: created_at and updated_at columns
  • How to Use Regular Expressions in SQLAlchemy
  • SQLAlchemy: Ways to Find Results by a Keyword
  • SQLAlchemy: How to Connect to MySQL Database
  • SQLAlchemy: How to Bulk Insert Data into a Table
  • SQLAlchemy: How to Update a Record by ID
  • SQLAlchemy: Singular vs Plural Table Names