【问题标题】:db.Model vs db.Table in Flask-SQLAlchemyFlask-SQLAlchemy 中的 db.Model 与 db.Table
【发布时间】:2019-12-27 11:13:15
【问题描述】:

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

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

为什么?把所有东西都做成模型有什么缺点?我认为在数据库中声明表的统一方式看起来更干净。此外,稍后开发人员可能希望直接访问这些映射记录,而不是通过需要模型的关系。

【问题讨论】:

    标签: python sqlalchemy flask-sqlalchemy


    【解决方案1】:

    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.Table,它将节省您的时间。

    【讨论】:

    • 如果您确实需要存储有关关系的额外数据怎么办?
    • 然后使用db.Model
    猜你喜欢
    • 1970-01-01
    • 2018-12-20
    • 1970-01-01
    • 1970-01-01
    • 2016-06-16
    • 1970-01-01
    • 2017-02-22
    • 2015-03-25
    • 2014-02-23
    相关资源
    最近更新 更多