2012-07-02 6 views
0

J'ai une base de données MySQL avec la structure suivante et j'espérais que quelqu'un pourrait m'aider à convertir la requête SQL ci-dessous en SQLAlchemy.SQLAlchemy - Comment MySQL JOIN

structure de base de données:

**bottom:** 
id 
name 
middle_id 

**middle:** 
id 
name 
top_id 

**top:** 
id 
name 

Voici mes modèles:

class Bottom(db.Model): 
    id  = db.Column(db.Integer, primary_key=True) 
    name  = db.Column(db.String(64)) 
    middle_id = db.Column(db.Integer, db.ForeignKey('middle.id')) 
    middle = db.relationship('Middle', 
     backref=db.backref('bottoms', lazy='dynamic')) 

class Middle(db.Model): 
    id  = db.Column(db.Integer, primary_key=True) 
    name  = db.Column(db.String(64)) 
    top_id = db.Column(db.Integer, db.ForeignKey('top.id')) 
    top  = db.relationship('Top', 
     backref=db.backref('middles', lazy='dynamic')) 

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

Voici le SQL que je veux convertir en SQLAlchemy:

SELECT 
    b.*, 
    m.*, 
    t.* 
FROM bottom AS b 
    LEFT JOIN (SELECT id, name, top_id from middle) AS m on m.id = b.middle_id 
    LEFT JOIN (SELECT id, name FROM top) AS t on t.id = m.top_id 
WHERE b.name LIKE '%query%' OR m.name LIKE '%query%' OR t.name LIKE '%query%' 

Chaque entrée dans la table fond est lié à milieu, et chaque entrée dans milieu est lié à haut. Je veux interroger la base de données pour trouver toutes les entrées dans bottom dont le nom est LIKE% query%, et aussi les entrées pour toutes les entrées dans bottom dont le nom du milieu est LIKE% query%, et aussi les entrées pour toutes les entrées dans en bas Le nom de la partie supérieure du milieu est LIKE requête.

Je veux le convertir en sqlalchemy quelque chose comme ceci:

return db.session.query(Bottom).filter(or_(Bottom.name.like('%query%'), 
            Bottom.middle.name.like('%query%'), 
            Bottom.middle.top.name.like('%query%')) 
            )).all() 

En d'autres termes, si j'ai une entrée en bas qui est lié à une entrée au Moyen-Orient, et que l'entrée au Moyen-est lié à une entrée dans Top, si je recherche Top pour le nom approprié, il ne retournera pas l'entrée Middle qui lui est associée, mais l'entrée Bottom qui est liée à l'entrée Middle correspondante.

Voici un exemple:

données:

**bottom** 
id  1 
name  "Gus Fring" 
middle_id 1 

**middle** 
id  1 
name  "Jesse Pinkman" 
top_id 1 

**top** 
id  1 
name  "Walter White" 

Si je recherche "Walter White" il retournera pas la relation Moyen (Jesse Pinkman), mais plutôt de la relation de fond au Moyen- résultat de la relation (Gus Fring).

Merci d'avance :).

+0

être précis avec votre question .. http://stackoverflow.com/questions/11287909/mysql -multiple-union – manurajhada

+0

@manurajhada qu'est-ce que tu n'es pas clair sur? Quels sont les détails que je ne fournis pas qui aideraient? – user1492385

+0

@manurajhada Je l'ai mis à jour un peu, je ne sais pas si c'est plus clair maintenant. – user1492385

Répondre

1
name_filter = '%query%' 
qry = (session.query(Bottom). 
     outerjoin(Middle). 
     outerjoin(Top). 
     filter(or_(
      Bottom.name.like(name_filter), 
      Middle.name.like(name_filter), 
      Top.name.like(name_filter), 
      )) 
     ) 

Vous obtiendrez uniquement des instances de Bottom à la suite de cette exécution de requête. Si vous voulez vraiment tous les 3 d'entre eux comme un tuple (Bas, Moyen, Haut), il suffit de remplacer la partie query(...)-session.query(Bottom, Middle, Top).

+0

J'aime votre façon de répondre aux questions: je retire mon chapeau pour vous. – iChux