2015-09-21 33 views
1

使用例如外鍵對象從the Flask-SQLAlchemy Quickstart篩選記錄在SQLAlchemy的對象,如果該記錄有與此相關的

from datetime import datetime 

class Post(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    title = db.Column(db.String(80)) 
    body = db.Column(db.Text) 
    pub_date = db.Column(db.DateTime) 

    category_id = db.Column(db.Integer, db.ForeignKey('category.id')) 
    category = db.relationship('Category', 
     backref=db.backref('posts', lazy='dynamic')) 

    def __init__(self, title, body, category, pub_date=None): 
     self.title = title 
     self.body = body 
     if pub_date is None: 
      pub_date = datetime.utcnow() 
     self.pub_date = pub_date 
     self.category = category 

    def __repr__(self): 
     return '<Post %r>' % self.title 


class Category(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(50)) 

    def __init__(self, name): 
     self.name = name 

    def __repr__(self): 
     return '<Category %r>' % self.name 

我已經重新創建的類別和職位相同的方式例如:

>>> py = Category('Python') 
>>> p = Post('Hello Python!', 'Python is pretty cool', py) 
>>> db.session.add(py) 
>>> db.session.add(p) 
>>> py.posts.all() 
[<Post 'Hello Python!'>] 

然後,添加一個新的類別:

>>> ru = Category('Ruby') 
>>> db.session.add(ru) 

如何構建一個查詢獲取有帖子的所有類別。

想這樣做,但使用SQLAlchemy的過濾器來代替:

>>> categories_with_post = [] 
>>> For c in Category.query.all(): 
...  if len(c.posts.all()) > 0: 
...   categories_with_post.append(c) 

回答

2

因爲所有你想要的是有文章分類,你可以嘗試這樣的事:

from sqlalchemy import distinct 
db.session.query(distinct(Category.id), Category).join(Post.category).all() 

連接將阻止任何沒有帖子的類別被返回。

注意不同功能的用法,它將防止類別在多個帖子指向同一類別時重複。但是它不能用於Category類本身,所以我在Category.id屬性中使用它,並添加Category作爲第二個參數來獲取整個對象。它將返回(id,Category)元組的列表。

+2

根本沒有必要使用不同的或查詢ID。只需查詢「類別」,SQLAlchemy就會崩潰重複的實例。 'Category.query.join(Category.posts).all()'會查找至少有一個帖子的所有類別。 – davidism