删除ManyToMany中间表中的行

时间:2010-09-27 23:30:22

标签: python sqlite orm sqlalchemy python-elixir

我有两个表,它们之间有ManyToMany关系。有时我需要刷新 数据库所以我删除了两个表中的元素。但是,已删除行之间的关系仍存储在自动创建的中间表中。

为了澄清问题,这里有一个小代码:

from elixir import *

metadata.bind = "sqlite:///test.db"
metadata.bind.echo = True

options_defaults['shortnames'] = True

class A(Entity):
    name = Field(Unicode(128))
    blist = ManyToMany("B",cascade='all,delete, delete-orphan')

class B(Entity):
    name = Field(Unicode(128))
    alist = ManyToMany("A",cascade='all,delete, delete-orphan') 

setup_all()
create_all()


a1 = A()
a1.name = u"john"

b1 = B()
b1.name = u"blue"

a1.blist.append(b1)

session.commit()

session.query(A).delete()
session.query(B).delete()

session.commit()

sqlite数据库的转储现在包含:

sqlite> .dump
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE a (
    id INTEGER NOT NULL, 
    name VARCHAR(128), 
    PRIMARY KEY (id)
);
CREATE TABLE b (
    id INTEGER NOT NULL, 
    name VARCHAR(128), 
    PRIMARY KEY (id)
);
CREATE TABLE b_alist__a_blist (
    a_id INTEGER NOT NULL, 
    b_id INTEGER NOT NULL, 
    PRIMARY KEY (a_id, b_id), 
    CONSTRAINT a_blist_fk FOREIGN KEY(a_id) REFERENCES a (id), 
    CONSTRAINT b_alist_fk FOREIGN KEY(b_id) REFERENCES b (id)
);
INSERT INTO "b_alist__a_blist" VALUES(1,1);
COMMIT;

我希望删除a1或b1时清空“b_alist__a_blist”表。

如果不使用SQLite不支持的ON DELETE语句,这是否可行?

由于我当然不是唯一一个使用与Elixir的ManyToMany关系的人,因此解决这个问题的方法可能微不足道。

上面给出的代码会生成sqlalchemy警告:

  

SQLAlchemy的/ ORM / properties.py:842:   SAWarning:在B.alist上,删除孤儿   a不支持级联   多对多或多对一   single_parent不是的关系   组。设置single_parent = True   关系()。
  self._determine_direction()

这只是因为我现在正在随意尝试在此ManyToMany关系中添加级联选项。这应该是delete-orphan不是正确选项的标志。

1 个答案:

答案 0 :(得分:1)

我想我找到了答案。 首先,问题与sqlalchemy单独相同

然后,这似乎只有在使用这种语法时才会发生:

session.query(B).delete()

但是可以使用以下方法获得所需的行为:

session.delete(b)  #where b is an instance of B

每个b的session.delete(b)的简单迭代可能会成功。

也许有人可以评论session.query().delete()session.delete() ...

的差异