factory-boy subfactory passes object instead of key
Asked Answered
D

2

7

I am using factory boy with SQLAlchemy.

I am trying to create Fact objects, and I want factory boy to generate PatientDim objects that are foreign keys to Fact. But Subfactory doesn't pass the key, instead it passes the entire object to the foreignkey field.

How can I only pass the PatientDim key thru Subfactory?

Factories.py

class FactFactory(SQLAlchemyModelFactory):
    class Meta:
        model = models.Fact
        sqlalchemy_session = common.Session

    patient_id = factory.SubFactory(PatientDimFactory)

class PatientDimFactory(SQLAlchemyModelFactory):
    class Meta:
        model = models.PatientDim
        sqlalchemy_session = common.Session

Models.py

class Fact(TimeStampedModel):
    class Meta:
        db_table = 'fact'

    id = Column(Integer, primary_key=True)
    patient_id = Column('patient_id', Integer, ForeignKey(PatientDim.__table__.c.id), nullable=False)
    patient = relationship(PatientDim, foreign_keys='Fact.patient_id' )

Base = declarative_base()
class PatientDim(TimestampMixin, Base):
    __tablename__ = 'patient_dim'

    id = Column('id', Integer, primary_key=True)
Dunnock answered 16/11, 2016 at 4:45 Comment(1)
One year later, no answer. Got this figured out?Gunnery
B
3

This looks like the same issue I found in this question: Why isn't SQLAlchemy translating this object generated by a FactoryBoy SubFactory into a foreign key? Based on that, the issue is this names the SubFactory based on the patient_id column and not the relationship patient.

In the examples here: https://github.com/FactoryBoy/factory_boy/blob/master/examples/flask_alchemy/demoapp_factories.py you can see they name the SubFactory based on the relationship, not the column for the foreign key. So it looks like updating that to patient = factory.SubFactory(PatientDimFactory) should work.

Brae answered 14/8, 2020 at 19:41 Comment(1)
Thank you, that linked question is useful. It does matter what name is specified in backref= of the relationship.Daiquiri
R
2

My today's workaround:

Generate dict data from Factory

import factory
data = factory.build(dict, FACTORY_CLASS=FactFactory)

Create ForeignKey/subFactory object

patient_dim = PatientDimFactory()
    

Change the foreignKey object in created data

data['patient_id '] = patient_dim.pk

Use crated data in a create Form

form = MyCrateForm(data=data)
Redskin answered 27/12, 2018 at 14:39 Comment(1)
Would be good if you add explicit 'import factory\n ... \n' in first example, at first I didn't realize that 'factory' was a module name, not a variable referring to some factory.Martellato

© 2022 - 2024 — McMap. All rights reserved.