Reputation: 7192
I am creating SQLAlchemy class that represents user credentials.
I want to have field password
that stores hashed value of password. Therefore I would like to override its behavior the following way:
When assigned credentials.password = value
it actually stores hash of the value
When comparing credentials.password == value
it actually compares with hash of the value
I have read the following part of SQLAlchemy documentation http://docs.sqlalchemy.org/en/rel_0_7/orm/mapper_config.html#using-descriptors-and-hybrids
And I think I do understand how to solve the issue number 1.
I am however unsure, how to do second point. Is there a way to do it the safe way (without breaking SQLAlchemy)?
Here is the example model:
class Credentials(Base):
__tablename__ = 'credentials'
id = Column(Integer, primary_key=True)
_password = Column('password', String)
@hybrid_property
def password(self):
return self._password
@password.setter(self):
self._password = hash(self._password)
Upvotes: 3
Views: 2527
Reputation: 8545
For comparing, since you can't un-hash the password, you would need to create a custom type for the Column class, that over-rides the eq operator:
class MyPasswordType(String):
class comparator_factory(String.Comparator):
def __eq__(self, other):
return self.operate(operators.eq, hash(other))
Have a look at: http://docs.sqlalchemy.org/en/latest/core/types.html#types-operators
And http://docs.sqlalchemy.org/en/latest/core/types.html#sqlalchemy.types.TypeEngine.comparator_factory
To set you just need to pass in the value:
@password.setter
def password(self, value):
self._password = hash(value)
Upvotes: 2