【问题标题】:duplicate key error on relationship of foreign key on multiple tables多个表上外键关系的重复键错误
【发布时间】:2016-02-22 12:17:55
【问题描述】:

我正在尝试将数据插入到具有映射到另一个表的 ID 的表中,并且我希望它创建我的关系所需的数据...问题是在父级中,我有另一个关系,并且在孩子,我也与父母的孩子有关......见下文:

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

问题是,当我使用工厂插入 Parent 时,显然它尝试插入 childb 表两次,因为它在 parent 和 childa 中被引用,因为我不断获得 childb_id 的重复键......知道如何防止这种情况发生?

我创建工厂的方式是创建一个 Parent 对象并提交会话:

Parent()
Session.commit()

【问题讨论】:

  • 如何“使用工厂插入Parent”?您可以发布 Parent 和 ChildA 的工厂吗?
  • 我已根据您的要求修改了问题

标签: python sqlalchemy factory-boy


【解决方案1】:

在后台,您对ParentTable() 的调用将转换为:

  1. 致电ChildATable()
  2. ChildATable()内,拨打ChildBTable()
  3. 再次致电ChildBTable(),这次来自ParentTable()

如果您希望您的两个工厂使用相同的 ChildB() 对象,您可以按如下方式更改您的 ParentTable() 工厂:

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)

【讨论】:

    【解决方案2】:

    我怀疑您在两个子工厂中获得的n 编号相同。可以试试这样的吗?

    class ParentTable(factory.alchemy.SQLAlchemyModelFactory)
        class Meta:
            ....
    
        parent_field = factory.Sequence(lambda n: 2*n + 1)
        childa = factory.SubFactory(ChildA)
        childb = factory.SubFactory(ChildB)
    

    【讨论】:

      猜你喜欢
      • 2011-04-01
      • 2015-07-16
      • 2018-05-30
      • 2020-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-09
      相关资源
      最近更新 更多