Python的SQLAlchemy不会清除二级(多对多)表吗?

But*_*840 9 python many-to-many sqlalchemy

UserTasks 之间有多对多的关系.当我删除Task或删除时,我希望清除"辅助表"(意思是,促进多对多关系的表)User.如何为此配置SQLAlchemy?

这是一些示例python代码,它演示了我遇到的问题.注意:此代码完全独立,只需要sqlalchemy模块.如果您复制并粘贴此代码,您应该能够在没有任何副作用的情况下运行它并自己查看相同的行为.脚本的最后一行显示删除相应任务时未删除"辅助表"中的相关行.在这个例子中,所有的断言都通过了.

from sqlalchemy import create_engine, Column, Integer, Text, Table, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import Session, relationship

Model = declarative_base()

class User(Model):
    __tablename__ = 'users'
    id = Column('user_id', Integer, primary_key=True)
    email = Column('email', Text, unique=True)

    def __init__(self, email):
        self.email = email

user_tasks = Table('user_tasks', Model.metadata,
    Column('user_id', Integer, ForeignKey('users.user_id')),
    Column('task_id', Integer, ForeignKey('tasks.task_id')))

class Task(Model):
    __tablename__ = 'tasks'
    id = Column('task_id', Integer, primary_key=True)
    description = Column('description', Text)
    assigned_to = relationship('User', secondary=user_tasks, backref='tasks')

    def __init__(self, description):
        self.description = description

if __name__ == '__main__':
    engine = create_engine('sqlite:///:memory:')
    Model.metadata.create_all(engine)
    s = Session(engine)
    the_user = User('user')
    s.add(the_user)
    s.commit()
    assert s.query(User).all() == [the_user]
    user_task = Task('user_one task')
    user_task.assigned_to.append(the_user)
    s.add(user_task)
    s.commit()
    assert s.query(Task).all() == [user_task]
    assert s.query(user_tasks).all() == [(1,1)]
    s.query(Task).delete()
    s.commit()
    assert s.query(Task).all() == []
    assert s.query(User).all() == [the_user]
    assert s.query(user_tasks).all() == [(1,1)]  # I was expecting [] .
Run Code Online (Sandbox Code Playgroud)

zzz*_*eek 12

delete(synchronize_session='evaluate'):

该方法不提供Python内级联关系 - 假设ON DELETE CASCADE配置为需要它的任何外键引用.会话需要过期(在commit()之后自动发生,或调用expire_all()),以便正确表示要删除或删除orphan级联的依赖对象的状态.

也就是说,SQLAlchemy无法找到您正在删除的所有Task对象,并找出要从user_tasks中删除的每一行 - 最好的方法是在外键上使用ON DELETE CASCADE(不起作用)使用MySQL MyISAM表或SQLite(如果未启用外键):

http://docs.sqlalchemy.org/en/latest/core/constraints.html#on-update-and-on-delete