factory_boy
factory_boy copied to clipboard
Transform a field before save to database
I am trying to create UserFactory with sqlalchemy engine. The problem is I need to hash password before saving to database. I tried many things but nothing worked.
I tried to use lazy attributes but it looks like I can use only not lazy attributes i lambda body. I tried post_generate hook, but it looks like row is saved before that hook. I found transformer but it looks like it didn't exist now. I tried to override _create function, but didn't know how to call super there (and would have to override _build too).
class UserFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta:
model = UserModel
sqlalchemy_session = test_db
sqlalchemy_session_persistence = "commit"
username = factory.Faker("pystr")
password = factory.transform(lambda pass: my_hash(pass)) # how to achieve that?
Thanks in advance!
The Transformer is what you are looking for, but needs to be released. @rbarrois usually handles the releases, he schedules time to handle the support for bugs reported.
In the meantime, you can make do with LazyFunction
.
class UserFactory(SQLAlchemyModelFactory):
class Meta:
model = UserModel
sqlalchemy_session = test_db
sqlalchemy_session_persistence = "commit"
password = factory.LazyFunction(lambda: make_pass("hunter2"))
# Create a user with password hunter2
UserFactory.create()
# Create a user with password foo
UserFactory.create(make_pass("foo"))
@francoisfreitag Thank you for reply! Unfortunately it doesn't solve my problem because I cannot still just pass raw password into create function and it cause much code redundance. But it's not so crucial that I couldn't wait unit transformers will appear ;)
And... what is the reason of LazyFunction? Wouldn't that be the same?
password = make_pass("hunter2")
That’s correct, password = make_pass("hunter2")
would be the same as using a LazyFunction
. It would even be slightly more efficient, as the value is resolved at import time, rather than on each factory call.