在Flask sqlalchemy文档中,给出了使用简单的多对多关系的示例:
tags = db.Table('tags',
db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')),
db.Column('page_id', db.Integer, db.ForeignKey('page.id'))
)
class Page(db.Model):
id = db.Column(db.Integer, primary_key=True)
tags = db.relationship('Tag', secondary=tags,
backref=db.backref('pages', lazy='dynamic'))
class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True)
可以使用以下语法来联系相关对象:
Page.tags
我想要完成的工作基本上是将下面的关系添加到上面的那个:
tag_children = db.Table('tag_children,',
db.Column('parent_id', db.Integer, db.ForeignKey('tags.tag_id')),
db.Column('child_id', db.Integer, db.ForeignKey('tags.tag_id'))
)
这样每个页面都附有标签,但每个标签在该页面的范围内可以有多个子标签。我已经为一个名为 cars 的页面做了一个展示案例,其中我有它的标签和各自的子标签。
(页)汽车:
上面的所有列表项都是标记对象
我希望能够使用以下语法来获取相关对象:
Page.tag.children
例如(下面的虚拟代码,但我想明确关系的目的是什么):
Cars.tesla.children
答案 0 :(得分:0)
我认为,您不需要tag_children
的另一个表格。尝试使用SQLAlchemy邻接列表:
class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey('tag.id'))
children = relationship("Tag",
backref=backref('parent', remote_side=[id])
)
使用此架构,您可以使用如下语法:
for tag in page.tags: # where page is a Page instance received from db
print tag.children
这是使用SQLAlchemy模型的常用语法。尝试使用它而不是建议的Cars.tesla.children
。
像Cars['tesla'].children
这样的东西可以通过getitem方法实现,但我认为,这种方式非常不明确。
完整的代码段:
class Page(Base):
__tablename__ = 'page'
id = Column(Integer, primary_key=True)
name = Column(String(256))
tags = relationship('Tag', secondary='tags',
backref=backref('pages', lazy='dynamic'))
def __str__(self):
return self.name
class Tag(Base):
__tablename__ = 'tag'
id = Column(Integer, primary_key=True)
name = Column(String(256))
parent_id = Column(Integer, ForeignKey('tag.id'))
children = relationship(
"Tag",
backref=backref('parent', remote_side=[id])
)
def __str__(self):
return self.name
class Tags(Base):
__tablename__ = 'tags'
tag_id = Column(Integer, ForeignKey('tag.id'), primary_key=True)
page_id = Column(Integer, ForeignKey('page.id'), primary_key=True)
测试用例:
# Create page and tags
session.add(Page(id=1, name="cars"))
session.add(Tag(id=1, name="Mercedes"))
session.add(Tag(id=2, name="A-series", parent_id=1))
session.add(Tag(id=3, name="B-series", parent_id=1))
session.add(Tag(id=4, name="C-series", parent_id=1))
session.add(Tag(id=5, name="Tesla"))
session.add(Tag(id=6, name="Tesla Roadster", parent_id=5))
session.add(Tag(id=7, name="Model X", parent_id=5))
session.add(Tag(id=8, name="Model S", parent_id=5))
session.add(Tag(id=9, name="Model 3", parent_id=5))
# Fill relation
session.add(Tags(tag_id=1, page_id=1))
session.add(Tags(tag_id=5, page_id=1))
session.commit()
print session.query(Page).get(1) # >>> cars
print session.query(Page).get(1).tags # >>> Mercedes, Tesla
print session.query(Page).get(1).tags[1].children # >>> Tesla models