Flask-SQLAlchemy中的db.Model与db.Table [英] db.Model vs db.Table in Flask-SQLAlchemy
问题描述
Flask-SQLAlchemy文档说多对多查找表不应子类db.Model,而应被编写为db.Tables.从文档中:
The Flask-SQLAlchemy docs say that many-to-many lookup tables should not subclass db.Model but instead be written as db.Tables. From the docs:
如果要使用多对多关系,则需要定义 用于该关系的帮助器表.对于这个帮手 强烈建议您不要使用模型,而是使用实际 桌子
If you want to use many-to-many relationships you will need to define a helper table that is used for the relationship. For this helper table it is strongly recommended to not use a model but an actual table
为什么?使一切成为模型的不利之处是什么?我认为采用统一的方式在数据库中声明表看起来更干净.另外,有可能以后某个时间,开发人员将需要直接访问这些映射记录,而不是通过需要模型的关系来访问.
Why? What are the downsides to making everything a model? I think it looks cleaner to have a unified way of declaring tables in the database. Also, it's possible that sometime later a developer will want to access those mapping records directly, rather than through a relationship, which would require a model.
推荐答案
db.Table
更简单.
The db.Table
is more simple.
当您通过db.Table
定义多对多关系时,SQLAlchemy将接替您并完成大部分工作.
When you define a many-to-many relationship through db.Table
, SQLAlchemy would take over and do most of the job for you.
因此,假设我们与具有以下Table
和Model
定义的帖子和标签有关系:
So, assuming that we have a relationship with posts and tags with the following Table
and Model
definitions:
表格:
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)
插入和删除
如文档:
relationship()的第二个参数所独有的行为是,在添加或从集合中删除对象时,此处指定的表会自动受到INSERT和DELETE语句的约束.无需手动从该表中删除.从集合中删除记录的行为将使行在刷新时被删除.
A behavior which is unique to the secondary argument to relationship() is that the Table which is specified here is automatically subject to INSERT and DELETE statements, as objects are added or removed from the collection. There is no need to delete from this table manually. The act of removing a record from the collection will have the effect of the row being deleted on flush.
使用db.Table
,您可以执行以下操作:
With db.Table
, you can do something like this:
>>> post.tags.append(tag_foo)
>>> db.session.commit()
您无需将其添加到会话中,则可以使用remove()
删除关系:
You needn't add it into session, then you can delete a relationship with remove()
:
>>> post.tags.remove(tag_foo)
>>> db.session.commit()
但是,如果使用db.Model
,则必须执行以下操作(Tagging
是Model类):
However, if you use db.Model
, you have to do something like this (Tagging
is the Model class):
>>> tagging = Tagging(post=post_foo, tag=tag_bar)
>>> db.session.add(tagging)
>>> db.session.commit()
然后将其删除,如下所示:
then delete it like this:
>>> 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
,它将节省您的时间.
In a word, if you don't need to store extra data about the relationship, just use db.Table
, it will save your time.
这篇关于Flask-SQLAlchemy中的db.Model与db.Table的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!