python - SQLAlchemy: cascade delete -


i must missing trivial sqlalchemy's cascade options because cannot simple cascade delete operate correctly -- if parent element deleted, children persist, null foreign keys.

i've put concise test case here:

from sqlalchemy import column, integer, foreignkey sqlalchemy.orm import relationship  sqlalchemy import create_engine sqlalchemy.orm import sessionmaker sqlalchemy.ext.declarative import declarative_base  base = declarative_base()  class parent(base):     __tablename__ = "parent"     id = column(integer, primary_key = true)  class child(base):     __tablename__ = "child"     id = column(integer, primary_key = true)     parentid = column(integer, foreignkey(parent.id))     parent = relationship(parent, cascade = "all,delete", backref = "children")  engine = create_engine("sqlite:///:memory:") base.metadata.create_all(engine) session = sessionmaker(bind=engine)  session = session()  parent = parent() parent.children.append(child()) parent.children.append(child()) parent.children.append(child())  session.add(parent) session.commit()  print "before delete, children = {0}".format(session.query(child).count()) print "before delete, parent = {0}".format(session.query(parent).count())  session.delete(parent) session.commit()  print "after delete, children = {0}".format(session.query(child).count()) print "after delete parent = {0}".format(session.query(parent).count())  session.close() 

output:

before delete, children = 3 before delete, parent = 1 after delete, children = 3 after delete parent = 0 

there simple, one-to-many relationship between parent , child. script creates parent, adds 3 children, commits. next, deletes parent, children persist. why? how make children cascade delete?

the problem sqlalchemy considers child parent, because defined relationship (it doesn't care called "child" of course).

if define relationship on parent class instead, work:

children = relationship("child", cascade="all,delete", backref="parent") 

(note "child" string: allowed when using declarative style, able refer class not yet defined)

you might want add delete-orphan (delete causes children deleted when parent gets deleted, delete-orphan deletes children "removed" parent, if parent not deleted)

edit: found out: if really want define relationship on child class, can so, have define cascade on backref (by creating backref explicitly), this:

parent = relationship(parent, backref=backref("children", cascade="all,delete")) 

(implying from sqlalchemy.orm import backref)


Comments

Popular posts from this blog

apache - Add omitted ? to URLs -

redirect - bbPress Forum - rewrite to wwww.mysite prohibits login -

php - How can I stop spam on my custom forum/blog? -