db.Model与Flask-SQLAlchemy中的db.Table

时间:2017-07-11 21:40:34

标签: python flask flask-sqlalchemy

Flask-SQLAlchemy docs表示多对多查找表不应该是db.Model的子类,而应该写成db.Tables。来自文档:

  

如果您想使用多对多关系,则需要定义   用于关系的帮助程序表。对于这个帮手   表强烈建议不要使用模型而是使用实际模型   表

为什么呢?将一切变成模型的缺点是什么?我认为在数据库中使用统一的方式声明表格看起来更清晰。此外,有时候开发人员可能希望直接访问这些映射记录,而不是通过需要模型的关系。

1 个答案:

答案 0 :(得分:5)

db.Table更简单。

当您通过db.Table定义多对多关系时,SQLAlchemy将接管并完成大部分工作。

因此,假设我们与包含以下TableModel定义的帖子和标签有关系:

表:

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,就可以节省您的时间。