Dependency rule tried to blank out primary key in SQLAlchemy, when foreign key constraint is part of composite primary key

前端 未结 1 1002
自闭症患者
自闭症患者 2021-01-01 11:11

I have the following model definitions

class Foo(Base):
    __tablename__ = \'foo\'

    id = Column(Integer, primary_key=True)
    name = Column(String(200)         


        
相关标签:
1条回答
  • 2021-01-01 11:20

    Based on the comment by van I was able to work out a solution. The default relationship cascade is "save-update, merge". I had to set this to "save-update, merge, delete, delete-orphan".

    Adding delete by itself did not change the behavior, delete-orphan was necessary.

    Adding only delete-orphan made a deletion testcase fail, with the "dependency rule" assertion error, mentioned in the question:

    class HierarchicModelTest(unittest.TestCase):
        def test_delete_parent_object(self):
            foo = Foo(**foo_data).save()
            self.assertEqual(Foo.query.count(), 1)
            self.assertEqual(FooCycle.query.count(), 1)
    
            s = get_session()
            s.delete(foo)
            s.flush()
    
            self.assertEqual(Foo.query.count(), 0)
            self.assertEqual(FooCycle.query.count(), 0)
    

    --

      File "/home/xxx/xxx/xxx/backend/tests/test_core.py", line 128, in test_delete_parent_object
         s.flush()
      [...]
      AssertionError: Dependency rule tried to blank-out primary key column 'foocycle.foo_id' on instance '<FooCycle at 0x37a1710>'
    

    From the SQLAlchemy docs:

    delete-orphan cascade adds behavior to the delete cascade, such that a child object will be marked for deletion when it is de-associated from the parent, not just when the parent is marked for deletion.

    So, the correct definition of the FooCycle Model is

    class FooCycle(Base):
        __tablename__ = 'foocycle'
    
        foo_id = Column(
            String(50),
            ForeignKey('foo.id'),
            primary_key=True
        )
        some_number = Column(
            Integer,
            primary_key=True,
        )
    
        foo = relationship("Foo",
                           backref=backref("cycles",
                                            cascade="save-update, merge, "
                                                    "delete, delete-orphan"))
    
    0 讨论(0)
提交回复
热议问题