2016-04-10 17 views
0

İki tablo items ve games var.Bir tablodan gelen veriler birleştirildi

@app.route('/collection/<username>/<int:page>/<platform>/<path:path>')  
def collection(username, page=1, platform='DMG', path=None): 
    # first I get the user by his username 
    user = User.query.filter_by(username=username).first() 
    # then I get all items form the user and related games 
    items = user.items.join(Game) 
    # until now it works perfectly fine   
    # now I would like to obtain all titles from the joined table games 
    game_titles = items.filter(Game.title).all() 
    # but unfortunately I get only an empty list 

Neler eksik?

İşte

benim modeller:

class Game(db.Model): 
    __tablename__ = 'games' 
    id = db.Column(db.Integer, primary_key=True) 
    title = db.Column(db.String(64), index=True) 
    publisher = db.Column(db.String(32), index=True) 
    region = db.Column(db.String(3), index=True) 
    code_platform = db.Column(db.String(3), index=True) 
    code_identifier = db.Column(db.String(4), index=True) 
    code_region = db.Column(db.String(3), index=True) 
    code_revision = db.Column(db.String(1)) 
    code = db.Column(db.String(16), index=True, unique=True) 
    year = db.Column(db.Integer) 

    user_id = db.Column(db.Integer, db.ForeignKey('users.id')) 
    items = db.relationship('Item', backref='game', lazy='dynamic') 

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


class Item(db.Model): 
    __tablename__ = 'items' 
    id = db.Column(db.Integer, primary_key=True) 
    code = db.Column(db.String(8), index=True) 
    cart = db.Column(db.Boolean) 
    box = db.Column(db.Boolean) 
    manual = db.Column(db.Boolean) 

    user_id = db.Column(db.Integer, db.ForeignKey('users.id')) 
    game_id = db.Column(db.Integer, db.ForeignKey('game.id')) 

    def __repr__(self): 
     return '<Collection %r>' % (self.user_id) 
+0

"Tüm oyun başlıklarını filtrele" ile ne demek istiyorsunuz? – univerio

+0

@univerio 'Başlık' tablosundaki tüm oyunların 'oyunlar' tablosunda olmasını istiyorum. – ericMTR

cevap

1

ile bağlantı kurduğunuz masada listelenen oyunlar İki seçeneğiniz var. SQLAlchemy ORM kullanma:

game_titles = [i.game.title for i in user.items] 

bu daha verimli hale getirmek için, joinedload optimizasyonu uygulayabilirsiniz: İlgilendiğiniz tüm başlıklar (ve başka bir şey, alternatif

game_titles = [i.game.title for i in user.items.options(joinedload(Item.game))] 

, sen SQLAlchemy çekirdek kullanabilirsiniz):

game_titles = user.items.join(Item.game).with_entities(Game.title).all() 

yapabilirsiniz bile umurumda değil hiç değilse kullanıcı hakkında tamamen kullanıcı getirilirken atlamak:

ve db.session.query(...) başlangıçta kabul vardı aksine projection operator, karşılık oysa
game_titles = User.query.join(User.items).join(Item.game).filter(User.username == username).with_entities(Game.title).all() 
bir kenara

, .filter ve .filter_by, ilişkisel cebir içinde selection operator karşılık gelmektedir.

+0

Çok teşekkürler. Her iki seçenek de gayet iyi çalışıyor. Ve sadece ayrı olanları elde etmek için .distinct() 'user.items.join (Game) .with_entities (Game.code_platform) .distinct(). All()' gibi) uygulardım. Bunu SQLAlechemy ORM kullanarak yapmak da mümkün olabilir mi? – ericMTR

+0

@ericMTR Doğrudan değil. ORM ('list (set (game_titles))') kullanırsanız, python'da tekilleştirme işlemini yapmanız gerekecektir. – univerio

1

böyle bir şey deneyin: Esasen

items.join(Game).options(joinedload(Item.game, innerjoin=True)) 

, sen Oyunu ile katılmadan konum ve innerjoin kuvvetleri o yüzden sadece yapmak için nereye açıkça onu yükleyen (öğeler)

+0

Öneriniz için teşekkürler. Kısmen çalışır. 'Games = items.filter_by (title =' Adventure Island ') gibi özel oyunları filtreleyebilirim all() '. Ama yine de tüm oyunları bir seferde alacağım. Eğer oyunları denerim: games = items.filter (Game.title) .all() 'Boş bir liste alırım. Burada herhangi bir öneriniz var mı? – ericMTR

+0

@ericMTR 'filter'," tam sütun kümesini al ve sadece istediğim sütunları filtrele "anlamına gelmez. Bu, "** satırlarının tümünü ** alın ve yalnızca belirttiğim ölçütlerle eşleşen ** satırlara filtreleyin" anlamına gelir. – univerio

+0

@univerio Peki, istediğim belirli bir sütunun tüm öğelerini elde etmeyi nasıl başarabilirim? Tüm öğeleri sütun ** başlık ** tablo ** oyunlar ** item.join (Oyun) .options (joinload (Item.game, innerjoin = True)) 'dayalı olarak istiyorum? – ericMTR