SQLAlchemy系列教程:如何从结果中排除敏感信息

在使用 SQLAlchemy 获取数据时,妥善处理诸如密码之类的敏感信息至关重要。本文展示了在 SQLAlchemy 中排除查询结果中密码信息的各种方法。
在这里插入图片描述

使用延迟加载列

延迟加载列加载允许特定列仅在被访问时才被加载。将密码列标记为延迟加载:

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

按需加载列

如果您在某些情况下需要密码,但在其他情况下不需要,请按需加载:

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

使用load_only()

要显式地告诉SQLAlchemy加载哪些列,使用load_only()函数:

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()

直接排除列

也可以直接查询除‘ password ’列外的所有列:

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

安全方面的混合属性

使用 SQLAlchemy 的混合属性将密码封装在一个计算属性中,该属性不会明确地暴露密码:

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)

自动排除

对于更高级的方法,覆盖基类中的方法以默认情况下排除密码:

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

高级用法:覆盖查询类

对于跨不同查询经常需要排除列的情况,你可以覆盖默认的Query类,以在默认情况下包含排除功能。这可能是一个更高级的主题,因为它需要很好地理解自定义SQLAlchemy类。

class ExcludingQuery(Query):
    def exclude(self, *columns):
        return self.with_entities(*[c for c in self.column_descriptions if c['expr'] not in columns])

# Replace the query_property on the Base class
Base.query = session.query_property(query_cls=ExcludingQuery)

# Now you can write queries like:
query = User.query.exclude(User.nickname)
for user in query.all():
    print(user.name, user.fullname)

在实践中,这些方法可以根据具体需求组合使用。在选择一种方法时,理解对代码性能和可读性的影响是很重要的。

最后总结

总之,SQLAlchemy提供了各种方法来从查询结果中排除密码或任何敏感信息。明智地使用这些技术来确保应用程序的数据保持安全。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值