我有两个表,它们之间存在多对多关系。有时我需要刷新数据库,以便从两个表中删除元素。但是,已删除行之间的关系仍存储在自动创建的中间表中。
为了澄清问题,这里有一个小代码:
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 的多对多关系的人,所以这个问题的解决方案可能是微不足道的。
上面给出的代码会生成 sqlalchemy 警告:
sqlalchemy/orm/properties.py:842:SAWarning:在 B.alist 上,当未设置 single_parent 时,多对多或多对一关系不支持删除孤儿级联。在 relationship() 上设置 single_parent=True。
self._determine_direction()
这只是因为我现在随机尝试在这个 ManyToMany 关系中添加级联选项。这应该表明 delete-orphan 不是正确的选项。