Open timdiels opened 5 years ago
What about using Django's FK field to express the relationship between the two (which internally will use a bar_id
field)?
class Bar(models.Model):
pass
class LegacyFoo(models.Model):
bar = models.ForeignKey(Bar, null=True, on_delete=models.CASCADE)
class BarFactory(DjangoModelFactory):
class Meta:
model = Bar
class LegacyFooFactory(DjangoModelFactory):
class Meta:
model = LegacyFoo
class Params:
has_bar = Trait(
bar = SubFactory(BarFactory),
)
First, I think I got the naming backwards. bar_id
was supposed to be a reference to the legacy row. You can mentally substitute LegacyFoo
for UserV2
and Bar
for UserV1
.
The legacy tables are in a different DB, at the time it was on a different server even. So it is not possible to point an FK to it, or at least in MySQL it wasn't, switched to Postgres in the meantime. The use case is a legacy DB being migrated to a new DB; the migration is tested with these factories. The tests do put all tables in the same DB though.
FKs would be possible though when first copying the legacy tables to the new DB without making any changes yet. I prefer my own workaround to that though as it avoids the extra copy. I'll be able to get rid of these legacy/v1 factories after the migration, but thought I'd mention this problem in case someone else comes across it in the future.
The problem
Setting params with a trait seems to be unsupported currently. Not sure whether to consider this a bug but the docs on traits refer to 'fields', not 'params', so I opted with not-a-bug.
E.g.
Fails the second assert.
And when changing it to:
This results in:
This can be worked around with an exclude though:
Proposed solution
If not supporting params, it may help to add a note in the reference and introduction that traits cannot assign to params, only to fields. Else, add support for it; I'm not familiar with how factory_boy is implemented :)
Extra notes
Supporting assignment to params may allow one to forget about
exclude
(see #549)