forked from ScoDoc/ScoDoc
WIP: definition base en SQLAlchemy
This commit is contained in:
parent
186440293d
commit
1375c195ca
@ -128,6 +128,3 @@ def create_app(config_class=Config):
|
|||||||
app.logger.info("ScoDoc8 startup")
|
app.logger.info("ScoDoc8 startup")
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|
||||||
# from app import models
|
|
||||||
|
@ -17,17 +17,17 @@ class NotesFormation(db.Model):
|
|||||||
formation_id = db.synonym("id")
|
formation_id = db.synonym("id")
|
||||||
acronyme = db.Column(db.String(SHORT_STR_LEN), nullable=False)
|
acronyme = db.Column(db.String(SHORT_STR_LEN), nullable=False)
|
||||||
titre = db.Column(db.Text(), nullable=False)
|
titre = db.Column(db.Text(), nullable=False)
|
||||||
|
titre_officiel = db.Column(db.Text(), nullable=False)
|
||||||
version = db.Column(db.Integer, default=1)
|
version = db.Column(db.Integer, default=1)
|
||||||
formation_code = db.Column(db.String(SHORT_STR_LEN), nullable=False)
|
formation_code = db.Column(
|
||||||
|
db.String(SHORT_STR_LEN),
|
||||||
|
server_default=db.text("notes_newid_fcod()"),
|
||||||
|
nullable=False,
|
||||||
|
)
|
||||||
|
# nb: la fonction SQL notes_newid_fcod doit être créée à part
|
||||||
type_parcours = db.Column(db.Integer, default=0)
|
type_parcours = db.Column(db.Integer, default=0)
|
||||||
code_specialite = db.Column(db.String(SHORT_STR_LEN))
|
code_specialite = db.Column(db.String(SHORT_STR_LEN))
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
|
||||||
super(NotesFormation, self).__init__(**kwargs)
|
|
||||||
if self.formation_code is None:
|
|
||||||
# génère formation_code à la création
|
|
||||||
self.formation_code = f"FCOD{self.id:03d}"
|
|
||||||
|
|
||||||
|
|
||||||
class NotesUE(db.Model):
|
class NotesUE(db.Model):
|
||||||
"""Unité d'Enseignement"""
|
"""Unité d'Enseignement"""
|
||||||
@ -43,7 +43,13 @@ class NotesUE(db.Model):
|
|||||||
# Type d'UE: 0 normal ("fondamentale"), 1 "sport", 2 "projet et stage (LP)",
|
# Type d'UE: 0 normal ("fondamentale"), 1 "sport", 2 "projet et stage (LP)",
|
||||||
# 4 "élective"
|
# 4 "élective"
|
||||||
type = db.Column(db.Integer, default=0)
|
type = db.Column(db.Integer, default=0)
|
||||||
ue_code = db.Column(db.String(SHORT_STR_LEN), nullable=False)
|
# Les UE sont "compatibles" (pour la capitalisation) ssi elles ont ^m code
|
||||||
|
# note: la fonction SQL notes_newid_ucod doit être créée à part
|
||||||
|
ue_code = db.Column(
|
||||||
|
db.String(SHORT_STR_LEN),
|
||||||
|
server_default=db.text("notes_newid_ucod()"),
|
||||||
|
nullable=False,
|
||||||
|
)
|
||||||
ects = db.Column(db.Float) # nombre de credits ECTS
|
ects = db.Column(db.Float) # nombre de credits ECTS
|
||||||
is_external = db.Column(db.Boolean(), nullable=False, default=False)
|
is_external = db.Column(db.Boolean(), nullable=False, default=False)
|
||||||
# id de l'element pedagogique Apogee correspondant:
|
# id de l'element pedagogique Apogee correspondant:
|
||||||
@ -51,12 +57,6 @@ class NotesUE(db.Model):
|
|||||||
# coef UE, utilise seulement si l'option use_ue_coefs est activée:
|
# coef UE, utilise seulement si l'option use_ue_coefs est activée:
|
||||||
coefficient = db.Column(db.Float)
|
coefficient = db.Column(db.Float)
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
|
||||||
super(NotesUE, self).__init__(**kwargs)
|
|
||||||
if self.ue_code is None:
|
|
||||||
# génère code à la création
|
|
||||||
self.ue_code = f"UCOD{self.ue_id:03d}"
|
|
||||||
|
|
||||||
|
|
||||||
class NotesMatiere(db.Model):
|
class NotesMatiere(db.Model):
|
||||||
"""Matières: regroupe les modules d'une UE
|
"""Matières: regroupe les modules d'une UE
|
||||||
|
@ -54,6 +54,7 @@ class GroupDescr(db.Model):
|
|||||||
|
|
||||||
group_membership = db.Table(
|
group_membership = db.Table(
|
||||||
"group_membership",
|
"group_membership",
|
||||||
|
db.Column("id", db.Integer, primary_key=True), # was group_membership_id
|
||||||
db.Column("etudid", db.Integer, db.ForeignKey("identite.id")),
|
db.Column("etudid", db.Integer, db.ForeignKey("identite.id")),
|
||||||
db.Column("group_id", db.Integer, db.ForeignKey("group_descr.id")),
|
db.Column("group_id", db.Integer, db.ForeignKey("group_descr.id")),
|
||||||
db.UniqueConstraint("etudid", "group_id"),
|
db.UniqueConstraint("etudid", "group_id"),
|
||||||
|
@ -93,7 +93,9 @@ def SimpleDictFetch(query, args, cursor=None):
|
|||||||
|
|
||||||
|
|
||||||
def DBInsertDict(cnx, table, vals, commit=0, convert_empty_to_nulls=1):
|
def DBInsertDict(cnx, table, vals, commit=0, convert_empty_to_nulls=1):
|
||||||
"insert into table values in dict 'vals'"
|
"""insert into table values in dict 'vals'
|
||||||
|
Return: id de l'object créé
|
||||||
|
"""
|
||||||
cursor = cnx.cursor(cursor_factory=ScoDocCursor)
|
cursor = cnx.cursor(cursor_factory=ScoDocCursor)
|
||||||
if convert_empty_to_nulls:
|
if convert_empty_to_nulls:
|
||||||
for col in vals.keys():
|
for col in vals.keys():
|
||||||
@ -112,7 +114,8 @@ def DBInsertDict(cnx, table, vals, commit=0, convert_empty_to_nulls=1):
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
cursor.execute("insert into %s default values" % table)
|
cursor.execute("insert into %s default values" % table)
|
||||||
oid = cursor.lastrowid
|
cursor.execute(f"SELECT CURRVAL('{table}_id_seq')") # id créé
|
||||||
|
oid = cursor.fetchone()[0]
|
||||||
except:
|
except:
|
||||||
log("DBInsertDict: EXCEPTION !")
|
log("DBInsertDict: EXCEPTION !")
|
||||||
log("DBInsertDict: table=%s, vals=%s" % (str(table), str(vals)))
|
log("DBInsertDict: table=%s, vals=%s" % (str(table), str(vals)))
|
||||||
@ -272,7 +275,6 @@ class EditableTable(object):
|
|||||||
input_formators={},
|
input_formators={},
|
||||||
aux_tables=[],
|
aux_tables=[],
|
||||||
convert_null_outputs_to_empty=True,
|
convert_null_outputs_to_empty=True,
|
||||||
allow_set_id=False,
|
|
||||||
html_quote=True,
|
html_quote=True,
|
||||||
fields_creators={}, # { field : [ sql_command_to_create_it ] }
|
fields_creators={}, # { field : [ sql_command_to_create_it ] }
|
||||||
filter_nulls=True, # dont allow to set fields to null
|
filter_nulls=True, # dont allow to set fields to null
|
||||||
@ -281,11 +283,16 @@ class EditableTable(object):
|
|||||||
self.id_name = id_name
|
self.id_name = id_name
|
||||||
self.aux_tables = aux_tables
|
self.aux_tables = aux_tables
|
||||||
self.dbfields = dbfields
|
self.dbfields = dbfields
|
||||||
|
# DB remove object_id ("id" in db)
|
||||||
|
try:
|
||||||
|
i = self.dbfields.index(id_name)
|
||||||
|
self.dbfields = self.dbfields[:i] + self.dbfields[i + 1 :]
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
self.sortkey = sortkey
|
self.sortkey = sortkey
|
||||||
self.output_formators = output_formators
|
self.output_formators = output_formators
|
||||||
self.input_formators = input_formators
|
self.input_formators = input_formators
|
||||||
self.convert_null_outputs_to_empty = convert_null_outputs_to_empty
|
self.convert_null_outputs_to_empty = convert_null_outputs_to_empty
|
||||||
self.allow_set_id = allow_set_id
|
|
||||||
self.html_quote = html_quote
|
self.html_quote = html_quote
|
||||||
self.fields_creators = fields_creators
|
self.fields_creators = fields_creators
|
||||||
self.filter_nulls = filter_nulls
|
self.filter_nulls = filter_nulls
|
||||||
@ -294,7 +301,7 @@ class EditableTable(object):
|
|||||||
def create(self, cnx, args):
|
def create(self, cnx, args):
|
||||||
"create object in table"
|
"create object in table"
|
||||||
vals = dictfilter(args, self.dbfields, self.filter_nulls)
|
vals = dictfilter(args, self.dbfields, self.filter_nulls)
|
||||||
if self.id_name in vals and not self.allow_set_id:
|
if self.id_name in vals:
|
||||||
del vals[self.id_name]
|
del vals[self.id_name]
|
||||||
if self.html_quote:
|
if self.html_quote:
|
||||||
quote_dict(vals) # quote all HTML markup
|
quote_dict(vals) # quote all HTML markup
|
||||||
@ -303,14 +310,7 @@ class EditableTable(object):
|
|||||||
if title in self.input_formators:
|
if title in self.input_formators:
|
||||||
vals[title] = self.input_formators[title](vals[title])
|
vals[title] = self.input_formators[title](vals[title])
|
||||||
# insert
|
# insert
|
||||||
oid = DBInsertDict(cnx, self.table_name, vals, commit=True)
|
new_id = DBInsertDict(cnx, self.table_name, vals, commit=True)
|
||||||
# get back new object id
|
|
||||||
cursor = cnx.cursor(cursor_factory=ScoDocCursor)
|
|
||||||
cursor.execute(
|
|
||||||
"select %(id_name)s from %(table_name)s where oid=%(oid)s"
|
|
||||||
% {"id_name": self.id_name, "table_name": self.table_name, "oid": oid}
|
|
||||||
)
|
|
||||||
new_id = cursor.fetchone()[0]
|
|
||||||
return new_id
|
return new_id
|
||||||
|
|
||||||
def delete(self, cnx, oid, commit=True):
|
def delete(self, cnx, oid, commit=True):
|
||||||
@ -346,6 +346,8 @@ class EditableTable(object):
|
|||||||
)
|
)
|
||||||
for r in res:
|
for r in res:
|
||||||
self.format_output(r, disable_formatting=disable_formatting)
|
self.format_output(r, disable_formatting=disable_formatting)
|
||||||
|
# Add ScoDoc7 id:
|
||||||
|
r[self.id_name] = r["id"]
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def format_output(self, r, disable_formatting=False):
|
def format_output(self, r, disable_formatting=False):
|
||||||
@ -365,7 +367,10 @@ class EditableTable(object):
|
|||||||
|
|
||||||
def edit(self, cnx, args, html_quote=None):
|
def edit(self, cnx, args, html_quote=None):
|
||||||
"""Change fields"""
|
"""Change fields"""
|
||||||
|
# assert self.id_name in args
|
||||||
|
oid = args[self.id_name]
|
||||||
vals = dictfilter(args, self.dbfields, self.filter_nulls)
|
vals = dictfilter(args, self.dbfields, self.filter_nulls)
|
||||||
|
vals["id"] = oid
|
||||||
html_quote = html_quote or self.html_quote
|
html_quote = html_quote or self.html_quote
|
||||||
if html_quote:
|
if html_quote:
|
||||||
quote_dict(vals) # quote HTML
|
quote_dict(vals) # quote HTML
|
||||||
@ -381,7 +386,7 @@ class EditableTable(object):
|
|||||||
cnx,
|
cnx,
|
||||||
self.table_name,
|
self.table_name,
|
||||||
vals,
|
vals,
|
||||||
where="%s=%%(%s)s" % (self.id_name, self.id_name),
|
where="id=%(id)s",
|
||||||
commit=True,
|
commit=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -575,4 +580,4 @@ def copy_tuples_changing_attribute(
|
|||||||
t[column] = new_value
|
t[column] = new_value
|
||||||
for c in to_exclude:
|
for c in to_exclude:
|
||||||
del t[c]
|
del t[c]
|
||||||
DBInsertDict(cnx, table, t, convert_empty_to_nulls=False)
|
_ = DBInsertDict(cnx, table, t, convert_empty_to_nulls=False)
|
||||||
|
@ -127,9 +127,9 @@ class EvaluationCache(ScoDocCache):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def invalidate_sem(cls, formsemestre_id):
|
def invalidate_sem(cls, formsemestre_id):
|
||||||
"delete evaluations in this formsemestre from cache"
|
"delete evaluations in this formsemestre from cache"
|
||||||
req = """SELECT e.evaluation_id
|
req = """SELECT e.id
|
||||||
FROM notes_formsemestre s, notes_evaluation e, notes_moduleimpl m
|
FROM notes_formsemestre s, notes_evaluation e, notes_moduleimpl m
|
||||||
WHERE s.formsemestre_id = %(formsemestre_id)s and s.formsemestre_id=m.formsemestre_id and e.moduleimpl_id=m.moduleimpl_id;
|
WHERE s.id = %(formsemestre_id)s and s.id=m.id and e.moduleimpl_id=m.id;
|
||||||
"""
|
"""
|
||||||
evaluation_ids = [
|
evaluation_ids = [
|
||||||
x[0] for x in ndb.SimpleQuery(req, {"formsemestre_id": formsemestre_id})
|
x[0] for x in ndb.SimpleQuery(req, {"formsemestre_id": formsemestre_id})
|
||||||
@ -140,8 +140,7 @@ class EvaluationCache(ScoDocCache):
|
|||||||
def invalidate_all_sems(cls):
|
def invalidate_all_sems(cls):
|
||||||
"delete all evaluations from cache"
|
"delete all evaluations from cache"
|
||||||
evaluation_ids = [
|
evaluation_ids = [
|
||||||
x[0]
|
x[0] for x in ndb.SimpleQuery("SELECT id FROM notes_evaluation", "")
|
||||||
for x in ndb.SimpleQuery("SELECT evaluation_id FROM notes_evaluation", "")
|
|
||||||
]
|
]
|
||||||
cls.delete_many(evaluation_ids)
|
cls.delete_many(evaluation_ids)
|
||||||
|
|
||||||
@ -243,10 +242,7 @@ def invalidate_formsemestre( # was inval_cache( context, formsemestre_id=None,
|
|||||||
# clear all caches
|
# clear all caches
|
||||||
log("----- invalidate_formsemestre: clearing all caches -----")
|
log("----- invalidate_formsemestre: clearing all caches -----")
|
||||||
formsemestre_ids = [
|
formsemestre_ids = [
|
||||||
x[0]
|
x[0] for x in ndb.SimpleQuery("SELECT id FROM notes_formsemestre", "")
|
||||||
for x in ndb.SimpleQuery(
|
|
||||||
"SELECT formsemestre_id FROM notes_formsemestre", ""
|
|
||||||
)
|
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
formsemestre_ids = [
|
formsemestre_ids = [
|
||||||
|
@ -824,9 +824,10 @@ Si vous souhaitez modifier cette formation (par exemple pour y ajouter un module
|
|||||||
return "".join(H)
|
return "".join(H)
|
||||||
|
|
||||||
|
|
||||||
def ue_sharing_code(context, ue_code=None, ue_id=None, hide_ue_id=None):
|
def ue_sharing_code(context, ue_code=None, ue_id=None, hide_ue_id=False):
|
||||||
"""HTML list of UE sharing this code
|
"""HTML list of UE sharing this code
|
||||||
Either ue_code or ue_id may be specified.
|
Either ue_code or ue_id may be specified.
|
||||||
|
Si hide_ue_id, ne montre pas l'UE d'origine dans la liste
|
||||||
"""
|
"""
|
||||||
from app.scodoc import sco_formations
|
from app.scodoc import sco_formations
|
||||||
|
|
||||||
|
@ -267,7 +267,7 @@ _identiteEditor = ndb.EditableTable(
|
|||||||
},
|
},
|
||||||
output_formators={"date_naissance": ndb.DateISOtoDMY},
|
output_formators={"date_naissance": ndb.DateISOtoDMY},
|
||||||
convert_null_outputs_to_empty=True,
|
convert_null_outputs_to_empty=True,
|
||||||
allow_set_id=True, # car on specifie le code Apogee a la creation
|
# allow_set_id=True, # car on specifie le code Apogee a la creation #sco8
|
||||||
)
|
)
|
||||||
|
|
||||||
identite_delete = _identiteEditor.delete
|
identite_delete = _identiteEditor.delete
|
||||||
|
@ -1375,7 +1375,7 @@ def do_formsemestre_delete(context, formsemestre_id):
|
|||||||
e,
|
e,
|
||||||
)
|
)
|
||||||
ndb.SimpleQuery(
|
ndb.SimpleQuery(
|
||||||
"DELETE FROM notes_evaluation WHERE evaluation_id=%(evaluation_id)s",
|
"DELETE FROM notes_evaluation WHERE id=%(evaluation_id)s",
|
||||||
e,
|
e,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ def group_delete(context, group, force=False):
|
|||||||
# remove memberships:
|
# remove memberships:
|
||||||
ndb.SimpleQuery("DELETE FROM group_membership WHERE group_id=%(group_id)s", group)
|
ndb.SimpleQuery("DELETE FROM group_membership WHERE group_id=%(group_id)s", group)
|
||||||
# delete group:
|
# delete group:
|
||||||
ndb.SimpleQuery("DELETE FROM group_descr WHERE group_id=%(group_id)s", group)
|
ndb.SimpleQuery("DELETE FROM group_descr WHERE id=%(group_id)s", group)
|
||||||
|
|
||||||
|
|
||||||
def get_partition(context, partition_id):
|
def get_partition(context, partition_id):
|
||||||
@ -556,8 +556,8 @@ def change_etud_group_in_partition(
|
|||||||
partition = get_partition(context, group["partition_id"])
|
partition = get_partition(context, group["partition_id"])
|
||||||
# 1- Supprime membership dans cette partition
|
# 1- Supprime membership dans cette partition
|
||||||
ndb.SimpleQuery(
|
ndb.SimpleQuery(
|
||||||
"""DELETE FROM group_membership WHERE group_membership_id IN
|
"""DELETE FROM group_membership WHERE id IN
|
||||||
(SELECT gm.group_membership_id
|
(SELECT gm.id
|
||||||
FROM group_membership gm, group_descr gd
|
FROM group_membership gm, group_descr gd
|
||||||
WHERE gm.etudid=%(etudid)s AND gm.group_id=gd.group_id AND gd.partition_id=%(partition_id)s)""",
|
WHERE gm.etudid=%(etudid)s AND gm.group_id=gd.group_id AND gd.partition_id=%(partition_id)s)""",
|
||||||
{"etudid": etudid, "partition_id": partition["partition_id"]},
|
{"etudid": etudid, "partition_id": partition["partition_id"]},
|
||||||
|
@ -201,7 +201,7 @@ class BasePreferences(object):
|
|||||||
("pref_id", "name", "value", "formsemestre_id"),
|
("pref_id", "name", "value", "formsemestre_id"),
|
||||||
sortkey="name",
|
sortkey="name",
|
||||||
convert_null_outputs_to_empty=False,
|
convert_null_outputs_to_empty=False,
|
||||||
allow_set_id=True,
|
# allow_set_id=True, #sco8
|
||||||
html_quote=False, # car markup pdf reportlab (<b> etc)
|
html_quote=False, # car markup pdf reportlab (<b> etc)
|
||||||
filter_nulls=False,
|
filter_nulls=False,
|
||||||
)
|
)
|
||||||
|
@ -82,13 +82,9 @@ class ScoTag(object):
|
|||||||
# Create new tag:
|
# Create new tag:
|
||||||
# log("creating new tag: %s" % self.title)
|
# log("creating new tag: %s" % self.title)
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
oid = ndb.DBInsertDict(
|
self.tag_id = ndb.DBInsertDict(
|
||||||
cnx, self.tag_table, {"title": self.title}, commit=True
|
cnx, self.tag_table, {"title": self.title}, commit=True
|
||||||
)
|
)
|
||||||
self.tag_id = ndb.SimpleDictFetch(
|
|
||||||
"SELECT tag_id FROM " + self.tag_table + " WHERE oid=%(oid)s",
|
|
||||||
{"oid": oid},
|
|
||||||
)[0]["tag_id"]
|
|
||||||
if object_id:
|
if object_id:
|
||||||
self.tag_object(object_id)
|
self.tag_object(object_id)
|
||||||
|
|
||||||
@ -123,7 +119,14 @@ class ScoTag(object):
|
|||||||
if not r:
|
if not r:
|
||||||
# log("tag %s with %s" % (object_id, self.title))
|
# log("tag %s with %s" % (object_id, self.title))
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
ndb.DBInsertDict(cnx, self.assoc_table, args, commit=True)
|
query = f"""INSERT INTO {self.assoc_table}
|
||||||
|
(tag_id, f{self.obj_colname})
|
||||||
|
VALUES"""
|
||||||
|
ndb.SimpleQuery(
|
||||||
|
query + " (%(tag_id)s, %(object_id)s)",
|
||||||
|
{"tag_id": self.tag_id, "object_id": object_id},
|
||||||
|
)
|
||||||
|
cnx.commit()
|
||||||
|
|
||||||
def remove_tag_from_object(self, object_id):
|
def remove_tag_from_object(self, object_id):
|
||||||
"""Remove tag from module.
|
"""Remove tag from module.
|
||||||
|
Loading…
Reference in New Issue
Block a user