Ell*_*t C 6 python sqlalchemy flask flask-sqlalchemy
鉴于这种多对多的关系:
tagmap = db.Table('tagmap', db.Model.metadata,
db.Column('post_id', db.Integer, db.ForeignKey('posts.id'),
db.Column('tag_id', db.Integer, db.ForeignKey('tags.id'),)
class Post(db.Model):
__tablename__ = 'posts'
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.Text)
tags = db.relationship('Tag', secondary=tagmap, backref='posts')
class Tag(db.Model):
__tablename__ = 'tags'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
Run Code Online (Sandbox Code Playgroud)
您将如何构造查询以选择所有帖子,包括可关联的Tag对象的可迭代列表?
期望的查询结果结构:
[ <Post 1, "Blah", [<Tag "Goober">, <Tag "Mexico">]>,
<Post 2, "Daft Punk", [<Tag "French">]>,
<Post 3, "Slurpee", [<Tag "Diabetes">, <Tag "Tasty">, <Tag "Sugary">]>,
<Post 4, "Lasers", []> ]
Run Code Online (Sandbox Code Playgroud)
Jinja模板中所需的结果使用示例:
{% for post in posts %}
{{ post.text }}
<hr>
{% for tag in post.tags %}
{{ tag.name }},
{% endfor %}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)
编辑:
尝试扩展查询时,标记将不再包含在内.查看下面的查询失败:
Post.query.join(User)\
.options(db.joinedload(Post.tags))\
.order_by(Post.create_date.desc()).limit(5)\
.values(User.name.label('author'),
Post.create_date,
Post.text,)
Run Code Online (Sandbox Code Playgroud)
编辑2:
所以这个查询效果很好:
posts = db.session.query(Post, User.name.label('author')).join(User)\
.options(db.joinedload(Post.tags))\
.order_by(Post.created.desc()).limit(5)
Run Code Online (Sandbox Code Playgroud)
但如果我想对Post中的列进行选择,请选择:
# I only need the post text, nothing else
posts = db.session.query(Post.text, User.name.label('author')).join(User)\
.options(db.joinedload(Post.tags))\
.order_by(Post.created.desc()).limit(5)
Run Code Online (Sandbox Code Playgroud)
它开始快速崩溃:
ArgumentError: Query has only expression-based entities - can't find property named 'tags'.
Run Code Online (Sandbox Code Playgroud)
所以我尝试添加标签:
# Yes, I know this is wrong
posts = db.session.query(Post.text, Post.tags, User.name.label('author'))\
.join(User)\
.options(db.joinedload(Post.tags))\
.order_by(Post.created.desc()).limit(5)
Run Code Online (Sandbox Code Playgroud)
哪个仍然失败.
因此,如果您只想要父对象(Post)中的特定列,您在表达式中的位置说"我还想要标记"吗?
现在它并不是那么重要,但我认为知道它会很有用.或者甚至知道这是不可能的.
我假设你想使用渴望加载关系.你可以做到这一点通过设置lazy
在你们的关系关键字参数'joined'
或'subquery'
:
class Post(db.Model):
# ...
tags = db.relationship('Tag', secondary=tagmap, backref='posts',
lazy='joined') # Or lazy='subquery'
Run Code Online (Sandbox Code Playgroud)
或者您可以按查询设置它:
q = Post.query.options(db.joinedload(Post.tags)).all()
# Or db.subqueryload(Post.tags)
Run Code Online (Sandbox Code Playgroud)
有关更多详细信息,请参阅ORM教程和关系加载技术的Eager Loading部分.
归档时间: |
|
查看次数: |
5530 次 |
最近记录: |