2017-09-20 3 views
0

Je suis nouveau sur sqlalchemy. Donc toute aide est appréciée. J'ai une fonction qui construit mes requêtes pour mon application. Je lui passe une liste de tables à rejoindre.Jointure dynamique ORM SQLAlchemy ne renvoyant pas toutes les colonnes de toutes les tables jointes

Voici les extraits de code pertinents.

class Scope(Base): 
    entry = Column(String(512)) 
    location_id = Column(Integer, ForeignKey('location_id')) 
    type = Column(String(128)) 

class Location(Base): 
    id = Column(Integer, primary_key=True) 
    name = Column(String(512) 
    modified_by = Column(String(128)) 

instances = [Scope, Location] 
join_classes = [Location] 

queryset = session.query(*instances).join(*join_classes).all() 

Voici la requête SQL qui fonctionne (lorsque j'imprime queryset à l'écran avant la .Toutes()):

queryset: SELECT scope.id AS scope_id, scope.location_id AS scope_location_id, champ d'application. entrée AS scope_entry, scope.type AS scope_type, location.name AS location_name, location.modified_by AS location_modified_by,
du champ d'application REJOIGNEZ la situation sur location.id = scope.location_id

Mon résultat final est que je veux: une liste de dictionnaires pour toutes les colonnes (à partir des deux tables - comme la jointure interne régulière donne un seul table).

Cependant, je reçois la liste quand je tape (queryset) et quand j'essaie juste de faire [u._asdict() pour u QuerySet] qui est de savoir comment je retourne une liste de dictionnaires dans les requêtes n'ont une jointure, elle renvoie uniquement une liste de dictionnaires pour 1 colonne de chaque table (la colonne dans le __repr__.

J'ai besoin de toutes les colonnes des deux tables à retourner.

en ce moment, c'est comment est-ce que je reçois: [{'Scope': 192.168.0.0/24, 'Emplacement': principal}, ...]

je besoin de quelque chose comme, où toutes les colonnes de la jointure sont renvoyés dans une liste de dictionnaires: [{ « Scope.entry »: 192.168.0.0/24, « Scope.type »: « virtuel » , 'Location.name': principale, 'Location.modified_by': 'jim'}, ...]

Dans mon code, les instances & join_classes sont transmises dynamiquement et non codées en dur que les différentes fonctions passent la table les modèles à rejoindre (avec la table du 1er modèle étant la table sur laquelle tous les participants sont connectés). Je en ai besoin de travailler avec une jointure sur plusieurs tables

Modifier (mais toutes les tables seront joints à la 1ère table modèle, portée dans cet exemple.): Je je me suis finalement rendu compte devenais une liste d'objets de table sqlalchemy arrière. C'est pourquoi j'obtenais les valeurs __repr__ lors de l'affichage.

+0

Pourriez-vous améliorer la mise en forme de votre code? Cela améliorerait grandement la lisibilité de votre question. – FabienP

+0

Bien sûr, comment. Le seul code est dans la section de code de bloc. Je vais mettre en évidence le résultat que je reçois et le résultat que je veux. – user7675859

Répondre

0

Eh bien, écrire quelque chose de fait vous aidera à trouver la réponse.

Pour ceux qui pourraient bénéficier c'est ce que j'ai fait. Je suis sûr qu'il y a une façon plus éloquente de le faire, alors s'il vous plaît faites le moi savoir si c'est le cas.

J'ai finalement lu ma sortie correctement et j'ai réalisé qu'il me donnait 2 objets de modèle de table (1 par table jointe). J'ai ensuite itéré sur chacun d'eux, j'ai converti chaque itération en une liste de dictionnaires, puis j'ai fusionné ces dictionnaires de manière appropriée pour avoir une liste de dictionnaires comme une table de jointure interne me donnerait.

Voici une partie de mon code:

for obj in queryset: 
    result.append(queryset_to_dict(obj)) 

for r in result: 
    new_dict = {} 
    for inner in r: 
     new_dict = {**new_dict, **inner} 
    new_result.append(new_dict) 
  • Notez le queryset_to_dict est une fonction que j'ai créé pour convertir des objets modèle de table sqlalchemy à la liste des dictionnaires.