New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature: access already generated fields in custom generation #41
Comments
Hi. Well, the issue here is really the ordering of generated fields - if you have a field A that is dependent on field B's value, this will not work out of the box currently. The library iterates the So, before this enhancement can proceed we need to have a clear viable way of implementing this in a way that can be developed further. I invite you to add your ideas. |
Hi. I totally agree, I was also worried about the order. I think it is enough for all the realistic use cases I can think of that every field could only depend on a preceding one (it is also a good way to avoid circularities as an unwanted side effect). So I think it is completely satisfactory to somehow allow access for already generated fields and only those. I am still unsure about the right syntax and need to familiarise myself more with the internal workings of the generation process, but I will try to make a v1 PR and we could iterate on that if you agree. |
sure go ahead. Also, would be happy for some further input @lindycoder |
I do not have a strong opinion on this. I usually try to make data models that don't have interdependent fields because it's always a pain to generate data from. If one field is generated from the others i would vote for a In the case you're describing i would probably hide the factory.build() in a function that will control the input to the .build(). Regarding the feature/implementation: I think it would be cool if |
I completely agree that this use case is best to be avoided. On the other hand it could add a nice extra to the package. Adding this option to Use though seems straightforward I would not go with the arg inspection option to avoid backward incompatible change. I suggest something like: class MyFactory(ModelFactory):
__model__ = MyModel
@generate('special_field')
def type_specific_generator(self, v, values: dict[str, Any])
# do the magic (??? provide faker instance to help generation)
return generated value It is a second way of doing the same thing which is not ideal, but this way backward incompatibility could be avoided. It should throw and error if the same field has a |
well, so far we didnt use decorators in this package. its not a strict no, but I would prefer keeping the API logic the same. How about, instead of modifying |
I like this, just to be sure, I see something like this in my head: class MyFactory(ModelFactory):
__model__ = MyModel
dependant_field = Depends('field_name or list of names', callable_receiving_dependant_values, args, kwargs) And the the value returned by the callable would be the final value for |
Just throwing that here
And all post generated fields would be triggered at the end of everything else, in no particular order. If you introduce the direct dependency, we need to change the iteration of the |
Fair point, it could even become circular I guess |
@Goldziher, @lindycoder, I was away trying to accomplish what triggered this idea in the first place and I realised that it is almost inevitable to do custom post processing over the model factories if I want to consistently generate a complex database with meaningful cross connections in the data. It could be easily accomplished without the suggested feature by iterating through the generated models and directly modifying attributes before persisting them. So I suppose to drop this feature as unnecessary. |
Note that this feature could still be relevant for people that likes immutability and makes their classes |
Ok, for me simple is better and this feature is borderline too complex, although I'm not opposed to it. Feel free to close this issue unless you intend to contribute it. |
I contributed a first version, any feedback is welcome! |
very nice stuff. I reviewed |
Hi, thanks for this library! In my team we are currently using factory-boy and considering to start using this library. Would this be a good case for SQL relationships ? For example in SQLModel: class Hero(SQLModel, table=True):
...
team_id: Optional[int] = Field(default=None, foreign_key="team.id")
team: Optional[Team] = Relationship(back_populates="heroes") How would we make sure that In factory-boy this could be accomplished with class HeroFactory(SQLAlchemyModelFactory):
...
team_id = FuzzyInteger()
team = SubFactory(TeamFactory, team_id=SelfAttribute("..team_id") Does this issue intends to support the same use cases? Is there a feature like |
Hi there, You could certainly use it like so I think. Please open a separate issue after this feature is released if it does not satisfy your requirements. |
This feature has been released in v1.3.0 @blagasz. Thanks for your contribution! |
It would be a nice feature to have access to the already generated field values in a customised generator scenario, e.g.
I could even imagine some decorator or annotation based solution to the same problem, e.g.
The text was updated successfully, but these errors were encountered: