Pippo
Pippo

Reputation: 925

duplicate key error on relationship of foreign key on multiple tables

I am trying to insert data to a table which has an ID that maps to another table and I expect it to create data required for my relationship... The problem is that within the Parent, I have another relation, and in the Child, I also relate to the Child from the parent... See below:

class Parent(Base):
    parent_field = Column(Integer)
    childa_id = Column(Integer, ForeignKey(ChildATable.childa_id))
    childb_id = Column(Integer, ForeignKey(ChildBTable.childb_id))

    childa = relationship(ChildATable)
    childb = relationship(ChildBTable)


class ChildA(Base):
    childa_id = Column(Integer, primary_key=True)
    childb_id = Column(Integer, ForeignKey(ChildB.childb_id))


class ChildB(Base):
    childb_id = Column(Integer, primary_key=True)


class ParentTable(factory.alchemy.SQLAlchemyModelFactory)
    class Meta:
        ....

    parent_field = factory.Sequence(lambda n: n + 1)
    childa = factory.SubFactory(ChildA)
    childb = factory.SubFactory(ChildB)

class ChildATable(factory.alchemy.SQLAlchemyModelFactory)
    class Meta:
        ....

    childa_id = factory.Sequence(lambda n: n + 1)
    childb = factory.SubFactory(ChildB)

class ChildBTable(factory.alchemy.SQLAlchemyModelFactory)
    class Meta:
        ....

    childb_id = 1 #I need this to be hardcoded to 1

The problem is that when I use factory to insert Parent, apparently it tries to insert childb table twice given it's referenced in parent and childa, because I keep getting duplicate key for childb_id... ANy idea how to prevent this of happening?

The way I create the factory is by creating a Parent object and committing the session:

Parent()
Session.commit()

Upvotes: 0

Views: 360

Answers (2)

Xelnor
Xelnor

Reputation: 3589

Under the hood, your call to ParentTable() will translate to:

  1. Call ChildATable()
  2. Within ChildATable(), call ChildBTable()
  3. Call ChildBTable() again, this time from ParentTable()

If you want your two factories to use the same ChildB() object, you could alter your ParentTable() factory as follows:

class ParentTable(factory.alchemy.SQLAlchemyModelFactory)
    class Meta:
        ....

    parent_field = factory.Sequence(lambda n: n + 1)
    childa = factory.SubFactory(ChildA,
        # Forward our `childb` to the `ChildA()` factory
        childb=factory.SelfAttribute('..childb'),
    )
    childb = factory.SubFactory(ChildB)

Upvotes: 1

Oin
Oin

Reputation: 7529

I suspect you're getting the same number for n in the two subfactories. Can you try something like this?

class ParentTable(factory.alchemy.SQLAlchemyModelFactory)
    class Meta:
        ....

    parent_field = factory.Sequence(lambda n: 2*n + 1)
    childa = factory.SubFactory(ChildA)
    childb = factory.SubFactory(ChildB)

Upvotes: 0

Related Questions