2010-09-27 79 views
2

我有兩個表之間有ManyToMany關係。有時我需要刷新 數據庫,以便從兩個表中刪除元素。但是,刪除行之間的關係仍然存儲在自動創建的中間表內。刪除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; 

我想清空「b_alist__a_blist」表既可以當a1或b1被刪除。

這是可能的,而不使用SQLite不總是支持的ON DELETE語句?

因爲我當然不是唯一使用Elixir的ManyToMany關係的人,所以解決這個問題的方法可能很簡單。

上面給出的代碼生成SQLAlchemy的警告:

SQLAlchemy的/ ORM/properties.py:842: SAWarning:在B.alist,刪除孤兒不支持一個 多到 級聯-many或多對一 當single_parent不是 設置時的關係。在 關係()上設置single_parent = True。
self._determine_direction()

這只是因爲我現在隨機試圖在這個多對多的關係添加級聯選項。這應該是一個表明刪除孤兒不是正確的選項。

回答

1

我想我找到了答案。 首先,問題與sqlalchemy單獨相同。

然後,這似乎只能使用此語法時發生:

session.query(B).delete() 

但可以通過使用獲得所需的行爲:

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

session.delete(b)每個B A簡單的迭代可能再做的伎倆。

也許有人可以對此差異發表評論session.query().delete()session.delete() ...