2017-10-06 3 views
0

J'ai une table pour les journaux qui contient diverses informations sur les employés ex:Comment faites-vous beaucoup à beaucoup avec plus de 2 tables?

class Log(Model): 
    division_id = Column(Integer, ForeignKey('division.id'), nullable=False) 
    division = relationship("Division") 

    employee_id = Column(Integer, ForeignKey("employee.id"), nullable=False) 
    employee = relationship("Employee") 

    skill_id = Column(Integer, ForeignKey("skill.id"), nullable=False) 
    skill = relationship("Skill") 

    message = Column(String, default='OK', nullable=False) 
    date = Column(DateTime, default=NowTime(), nullable=True) 

Tableaux des employés et des compétences ressembler à ceci:

class Employee(Model): 
    id = Column(Integer, primary_key=True) 
    name = Column(String, unique=True, nullable=False) 
    division_id = Column(Integer, ForeignKey('division.id'), nullable=False) 
    division = relationship("Division") 

class Skill(Model): 
    id = Column(Integer, primary_key=True) 
    name = Column(String, unique=True, nullable=False) 

J'utilise actuellement Flask-AppBuilder et j'ai Skill View qui affiche tous les journaux pour la compétence sélectionnée en cours.

class LogView(ModelView): 
    datamodel = SQLAInterface(Log) 
    list_columns = ['division', 'employee', 'skill', 'message', 'date'] 
    show_template = 'appbuilder/general/model/show_cascade.html' 

class SkillLogView(ModelView): 
    datamodel = SQLAInterface(Skill) 
    list_columns = ['name'] 
    related_views = [LogView] 
    show_template = 'appbuilder/general/model/show_cascade.html' 

Dans SkillLogView, je souhaite également afficher une liste de noms d'employés possédant cette compétence.

Comment puis-je également obtenir les employés à partir des journaux qui se rapportent à la compétence actuelle? Je ne suis pas sûr de savoir comment le faire, mais je pensais que ce pourrait être un cas pour plusieurs à plusieurs. Le problème est qu'il y a 3 tables, pas 2.

Existe-t-il un moyen d'en faire beaucoup avec beaucoup plus de 2 tables?

Ou y a-t-il une autre façon d'accomplir ce que je veux faire?

Toute aide appréciée.

Répondre

0

Votre Employee n'a pas établi de relation avec Log, donc l'interrogation Employee en utilisant joindre avec Log pour un prédicat est difficile.

Cependant, vous pouvez simplement interroger le Log pour employee_id avec le skill_id comme sous-requête, chercher Employee avec le résultat donné.

# Subquery returns `employee_id` from `logs` with the given `skill_id` 
sq = session.query(Log.employee_id).\ 
    filter(Log.skill_id == skill_id).\ 
    subquery() 

# Fetch `Employee` that matches `employee_id` in `sq` 
q = session.query(Employee).\ 
    filter(Employee.employee_id.in_(sq)) 

employees = q.all() # or paginate, e.g. q.limit(..).all() 
+0

Merci pour l'aide Ivan! En outre, j'ai posté une autre méthode qui l'implémente au niveau du modèle de table. Vérifiez quand vous avez le temps. –

+0

Merci pour le partage. J'ai mentionné votre 'Votre employé n'a pas établi de relation avec Log ...', c'est exactement ce que préconise votre autre méthode. –

0

Il existe un exemple en ligne qui fait exactement cela!

Il a une table de personne, table de voiture, table de propriété de voiture.

Tout ce que je devais faire était de remplacer l'employé par une personne, de l'habileté à conduire une voiture et de me connecter à un véhicule.

URL de référence: Many-to-Many with association object and all relationships defined crashes on delete

code Mise à jour:

class Log(Model): 
    division_id = Column(Integer, ForeignKey('division.id'), nullable=False) 
    division = relationship("Division") 

    employee_id = Column(Integer, ForeignKey("employee.id"), nullable=False) 
    employee = relationship("Employee", backref=backref('log', passive_deletes='all')) 

    skill_id = Column(Integer, ForeignKey("skill.id"), nullable=False) 
    skill = relationship("Skill", backref=backref('log', passive_deletes='all')) 

    message = Column(String, default='OK', nullable=False) 
    date = Column(DateTime, default=NowTime(), nullable=True) 


class Skill(Model): 
    id = Column(Integer, primary_key=True) 
    name = Column(String, unique=True, nullable=False) 

    employees = relationship('Employee', secondary='log', backref='skill') 


class Employee(Model): 
    id = Column(Integer, primary_key=True) 
    name = Column(String, unique=True, nullable=False) 

    division_id = Column(Integer, ForeignKey('division.id'), nullable=False) 
    division = relationship("Division") 

    skills = relationship('Skill', secondary='log', backref='employee')