2009-08-14 5 views
3

Considérez une table comme ceci:sqlalchemy - regroupant des articles et itérer sur les sous-listes

| Name  | Version | Other | 
| ---------------------|-------| 
| Foo  | 1  | 'a' | 
| Foo  | 2  | 'b' | 
| Bar  | 5  | 'c' | 
| Baz  | 3  | 'd' | 
| Baz  | 4  | 'e' | 
| Baz  | 5  | 'f' | 
-------------------------------- 

Je voudrais écrire une déclaration de requête sqlalchemy à la liste tous les éléments (comme des objets Mapper, non seulement la colonne Nom) avec la version max: Foo-2-b, Bar-5-c, Baz-5-f. Je comprends que je devrais utiliser la méthode group_by, mais au-delà je suis perplexe quant à la façon de récupérer les sous-listes (et ensuite trouver l'élément max). La documentation de SQLAlchemy n'est apparemment pas très claire à ce sujet.

Dans le scénario réel, il existe de nombreuses autres colonnes (comme 'Autre') - c'est pourquoi j'ai besoin de renvoyer l'objet ligne réel (classe mappeur) plutôt que la valeur 'Nom'.

Répondre

6

Si vous avez besoin d'objets complets, vous aurez besoin de sélectionner des versions maximales par nom dans un sous-requête et rejoindre à cette:

max_versions = session.query(Cls.name, func.max(Cls.version).label('max_version'))\ 
         .group_by(Cls.name).subquery() 
objs = session.query(Cls).join((max_versions, 
      and_(Cls.name == max_versions.c.name, 
       Cls.version == max_versions.c.max_version) 
     )).all() 

cela se traduira par quelque chose comme ceci:

SELECT tbl.id AS tbl_id, tbl.name AS tbl_name, tbl.version AS tbl_version 
FROM tbl JOIN (SELECT tbl.name AS name, max(tbl.version) AS max_version 
FROM tbl GROUP BY tbl.name) AS anon_1 ON tbl.name = anon_1.name AND tbl.version = anon_1.max_version 

Soyez conscient que vous aurez obtenir plusieurs lignes avec le même nom s'il y a plusieurs lignes avec la version max.

+0

Merci; (Nom, version) est un jeu de clés primaires. –

-2

Voici le SQL que vous pouvez appeler avec la commande engine.execute:

select 
    t1.* 
from 
    table t1 
    inner join 
     (select 
      Name, 
      max(version) as Version 
     from 
      table 
     group by 
      name) s on 
     s.name = t1.name 
     and s.version = t1.version 
+0

En fait, je veux tout l'objet "row" (objet de classe mapper), plutôt que le nom. La table actuelle contient plusieurs autres colonnes d'intérêt. –

+0

.. et cet objet ligne doit correspondre à celui qui a la version max. Trouver? –

+0

Veuillez relire la question que vous venez d'éditer (pour clarifier). –

Questions connexes