Flask-SQLAlchemy docs表示多对多查找表不应该是db.Model的子类,而应该写成db.Tables。来自文档:
如果您想使用多对多关系,则需要定义 用于关系的帮助程序表。对于这个帮手 表强烈建议不要使用模型而是使用实际模型 表
为什么呢?将一切变成模型的缺点是什么?我认为在数据库中使用统一的方式声明表格看起来更清晰。此外,有时候开发人员可能希望直接访问这些映射记录,而不是通过需要模型的关系。
答案 0 :(得分:5)
db.Table
更简单。
当您通过db.Table
定义多对多关系时,SQLAlchemy将接管并完成大部分工作。
因此,假设我们与包含以下Table
和Model
定义的帖子和标签有关系:
表:
tagging = db.Table('tagging',
db.Column('post_id', db.Integer, db.ForeignKey('post.id')),
db.Column('tag_id', db.Integer, db.ForeignKey('tag.id'))
)
型号:
class Tagging(db.Model):
tag_id = db.Column(db.Integer, db.ForeignKey('tag.id'),
primary_key=True)
post_id = db.Column(db.Integer, db.ForeignKey('post.id'),
primary_key=True)
如docs中的描述:
对于relationship()的辅助参数唯一的行为是此处指定的表自动受INSERT和DELETE语句的约束,因为在集合中添加或删除了对象。无需手动从此表中删除。从集合中删除记录的行为将具有在刷新时删除行的效果。
使用db.Table
,您可以执行以下操作:
>>> post.tags.append(tag_foo)
>>> db.session.commit()
您无需将其添加到会话中,然后您可以删除与remove()
的关系:
>>> post.tags.remove(tag_foo)
>>> db.session.commit()
但是,如果您使用db.Model
,则必须执行以下操作(Tagging
是Model类):
>>> tagging = Tagging(post=post_foo, tag=tag_bar)
>>> db.session.add(tagging)
>>> db.session.commit()
然后将其删除:
>>> tagging = post.tags.filter_by(post_id=post.id).first()
>>> db.session.delete(tagging)
>>> db.session.commit()
使用db.Table
:
>>> post.tags.all()
>>> [<Tag 'foo'>, ...]
然后db.Model
:
>>> post.tags.all() # You only get Tagging item.
>>> [<Tagging 'post_foo -- tag_bar'>, ...]
>>> for tagging in post.tags:
>>> print tagging.tag # <Tag 'foo'>
总之,如果您不需要存储有关关系的额外数据,只需使用db.Tabel
,就可以节省您的时间。