From a53e2fff7b0d4f55c7d06e98b0ddf14c510aff32 Mon Sep 17 00:00:00 2001 From: Richard Hitier Date: Fri, 14 May 2021 11:00:14 +0200 Subject: [PATCH] New category/labels orm models --- app/commands/commands.py | 16 +++++++++------- app/models.py | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------ resources/lesia-btp.sqlite | Bin 196608 -> 0 bytes 3 files changed, 67 insertions(+), 19 deletions(-) diff --git a/app/commands/commands.py b/app/commands/commands.py index abc00c3..abcd95d 100644 --- a/app/commands/commands.py +++ b/app/commands/commands.py @@ -10,7 +10,7 @@ from sqlalchemy.exc import IntegrityError from sqlalchemy.sql import func from app.models import db, Agent, Service, Project, Capacity, Period, Charge, AgentStatus, Company, AgentBap, \ - AgentGrade, Category, Label, ProjectLabel + AgentGrade, Category, Label, ProjectLabel, CategoryLabel # TODO: rename to methods and add get_roles() from app.auth.models import User, _nameToRole, _roleToName @@ -313,8 +313,9 @@ def feed_from_lesia(): domain_category = Category(name="Domaine") domains = lesia_session.query(lesia_domains) for d in domains: - n_l = Label(name=d.nom, category=domain_category) - db.session.add(n_l) + n_l = Label(name=d.nom) + n_cl = CategoryLabel(category=domain_category, label=n_l ) + db.session.add(n_cl) db.session.commit() # Feed all lesia 'pôle' names and link to new category "Pôle" @@ -322,8 +323,9 @@ def feed_from_lesia(): pole_category = Category(name="Pôle") poles = lesia_session.query(lesia_poles) for p in poles: - n_l = Label(name=p.nom, category=pole_category) - db.session.add(n_l) + n_l = Label(name=p.nom) + n_cl = CategoryLabel(category=pole_category, label=n_l) + db.session.add(n_cl) db.session.commit() # Feed lesia project with proper "pôle" @@ -338,7 +340,7 @@ def feed_from_lesia(): pole_name = lesia_session.query(lesia_poles).filter(lesia_poles.id == p.pole_id).one().nom # search corresponding Label and store in ProjectLabel table n_l = Label.query.filter(Label.name == pole_name).one() - n_pl = ProjectLabel(project=n_p, category=n_l.category, label=n_l) + n_pl = ProjectLabel(project=n_p, label=n_l) db.session.add(n_pl) db.session.commit() @@ -350,7 +352,7 @@ def feed_from_lesia(): domain_name = lesia_session.query(lesia_domains).filter(lesia_domains.id == dp.domaine_id).one().nom n_p = Project.query.filter(Project.name == project_name).one() n_l = Label.query.filter(Label.name == domain_name).one() - n_pl = ProjectLabel(project=n_p, category=n_l.category, label=n_l) + n_pl = ProjectLabel(project=n_p, label=n_l) db.session.add(n_pl) # Some projects have 2 domain labels in lesia db # That is not allowed any more in the new model. diff --git a/app/models.py b/app/models.py index 848888c..4e776d0 100644 --- a/app/models.py +++ b/app/models.py @@ -41,36 +41,82 @@ class Formable: # # Categorized projects # +# There is one label list, +# each label belongs to one or more categories. +# +# The projects are labelled by one or more label. +# +# Thus this is modeled with classes +# Project, Label and Category +# And many_to_many association are done through +# ProjectLabel and CategoryLabel +# -class Project(db.Model): +class Project(db.Model, Formable): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String) labels = relationship("ProjectLabel", back_populates="project") + export_keys = ['name'] -class Category(db.Model): + def to_struct(self): + """ + overide parent method to include one key: agent.fullname + + Mainly we add the 'labels' element containing a dict + where category key contains labels for that project. + :return: + """ + _struct = super(Project, self).to_struct() + _struct['labels'] = {} + for _c in Category.query.all(): + category_labels = [] + for _l in self.labels: + if _l.label in [_cl.label for _cl in _c.labels]: + category_labels.append(_l.label.name) + _struct['labels'][_c.name] = category_labels + return _struct + + +class ProjectLabel(db.Model): + """ + Labelling projects. + On project can have many labels. + And one label will be set to many projects + """ id = db.Column(db.Integer, primary_key=True) - name = db.Column(db.String) - labels = relationship("Label", back_populates="category") - projects = relationship("ProjectLabel", back_populates="category") + project_id = db.Column(db.Integer, db.ForeignKey('project.id')) + label_id = db.Column(db.Integer, db.ForeignKey('label.id')) + project = relationship("Project", back_populates="labels") + label = relationship("Label", back_populates="projects") class Label(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String, unique=True) category_id = db.Column(db.Integer, db.ForeignKey('category.id')) - category = relationship("Category", back_populates="labels") projects = relationship("ProjectLabel", back_populates="label") + categories = relationship("CategoryLabel", back_populates="label") -class ProjectLabel(db.Model): - project_id = db.Column(db.Integer, db.ForeignKey('project.id'), primary_key=True) - category_id = db.Column(db.Integer, db.ForeignKey('category.id'), primary_key=True) +class CategoryLabel(db.Model): + """ + Categorizing labels: + one label can be added to many categories + one category hosts many labels + """ + id = db.Column(db.Integer, primary_key=True) + category_id = db.Column(db.Integer, db.ForeignKey('category.id')) label_id = db.Column(db.Integer, db.ForeignKey('label.id')) + category = relationship("Category", back_populates="labels") + label = relationship("Label", back_populates="categories") - project = relationship("Project", back_populates="labels") - category = relationship("Category", back_populates="projects") - label = relationship("Label", back_populates="projects") + +class Category(db.Model): + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String) + labels = relationship("Label", back_populates="category") + labels = relationship("CategoryLabel", back_populates="category") # diff --git a/resources/lesia-btp.sqlite b/resources/lesia-btp.sqlite index ddb7dcc..f74549a 100644 Binary files a/resources/lesia-btp.sqlite and b/resources/lesia-btp.sqlite differ -- libgit2 0.21.2