"""
Modèles du schéma gn_commons
"""
import os
from pathlib import Path
from collections import defaultdict
from flask import current_app
from sqlalchemy import ForeignKey, text
from sqlalchemy.orm import relationship, aliased
from sqlalchemy.sql import select, func
from sqlalchemy.dialects.postgresql import UUID
from geoalchemy2 import Geometry
from pypnnomenclature.models import TNomenclatures
from pypnusershub.db.models import User
from utils_flask_sqla.serializers import serializable
from utils_flask_sqla_geo.serializers import geoserializable
from geonature.utils.env import DB
@serializable
[docs]
class BibTablesLocation(DB.Model):
[docs]
__tablename__ = "bib_tables_location"
[docs]
__table_args__ = {"schema": "gn_commons"}
[docs]
id_table_location = DB.Column(DB.Integer, primary_key=True)
[docs]
table_desc = DB.Column(DB.Unicode)
[docs]
schema_name = DB.Column(DB.Unicode)
[docs]
table_name = DB.Column(DB.Unicode)
[docs]
pk_field = DB.Column(DB.Unicode)
[docs]
uuid_field_name = DB.Column(DB.Unicode)
[docs]
cor_module_dataset = DB.Table(
"cor_module_dataset",
DB.Column(
"id_module",
DB.Integer,
ForeignKey("gn_commons.t_modules.id_module"),
primary_key=True,
),
DB.Column(
"id_dataset",
DB.Integer,
ForeignKey("gn_meta.t_datasets.id_dataset"),
primary_key=True,
),
schema="gn_commons",
)
@serializable
[docs]
class CorModuleDataset(DB.Model):
[docs]
__tablename__ = "cor_module_dataset"
[docs]
__table_args__ = {"schema": "gn_commons", "extend_existing": True}
[docs]
id_module = DB.Column(
DB.Integer,
ForeignKey("gn_commons.t_modules.id_module"),
primary_key=True,
)
[docs]
id_dataset = DB.Column(
DB.Integer,
ForeignKey("gn_meta.t_datasets.id_dataset"),
primary_key=True,
)
# see https://docs.sqlalchemy.org/en/14/orm/basic_relationships.html#late-evaluation-of-relationship-arguments
[docs]
def _resolve_import_cor_object_module():
from geonature.core.gn_permissions.models import cor_object_module
return cor_object_module
@serializable
[docs]
class TModules(DB.Model):
[docs]
__tablename__ = "t_modules"
[docs]
__table_args__ = {"schema": "gn_commons"}
[docs]
class base_defaultdict(defaultdict):
"""
Avoid polymorphic error when polymorphic identities are declared
in database but absent from venv: fallback on base identity.
Taken from CTFd.
"""
[docs]
def __missing__(self, key):
return self["base"]
[docs]
type = DB.Column(DB.Unicode, nullable=False, server_default="base")
[docs]
__mapper_args__ = {
"polymorphic_on": "type",
"polymorphic_identity": "base",
"_polymorphic_map": base_defaultdict(),
}
[docs]
id_module = DB.Column(DB.Integer, primary_key=True)
[docs]
module_code = DB.Column(DB.Unicode)
[docs]
module_label = DB.Column(DB.Unicode)
[docs]
module_picto = DB.Column(DB.Unicode)
[docs]
module_desc = DB.Column(DB.Unicode)
[docs]
module_group = DB.Column(DB.Unicode)
[docs]
module_path = DB.Column(DB.Unicode)
[docs]
module_external_url = DB.Column(DB.Unicode)
[docs]
module_target = DB.Column(DB.Unicode)
[docs]
active_frontend = DB.Column(DB.Boolean)
[docs]
active_backend = DB.Column(DB.Boolean)
[docs]
module_doc_url = DB.Column(DB.Unicode)
[docs]
module_order = DB.Column(DB.Integer)
[docs]
ng_module = DB.Column(DB.Unicode(length=500))
[docs]
objects = DB.relationship(
"PermObject", secondary=lambda: _resolve_import_cor_object_module(), backref="modules"
)
# relationship datasets add via backref
[docs]
def __str__(self):
return self.module_label.capitalize()
@serializable(exclude=["base_dir"])
@serializable
[docs]
class TParameters(DB.Model):
[docs]
__tablename__ = "t_parameters"
[docs]
__table_args__ = {"schema": "gn_commons"}
[docs]
id_parameter = DB.Column(DB.Integer, primary_key=True)
[docs]
id_organism = DB.Column(DB.Integer, ForeignKey("utilisateurs.bib_organismes.id_organisme"))
[docs]
parameter_name = DB.Column(DB.Unicode)
[docs]
parameter_desc = DB.Column(DB.Unicode)
[docs]
parameter_value = DB.Column(DB.Unicode)
@serializable
[docs]
class TValidations(DB.Model):
[docs]
__tablename__ = "t_validations"
[docs]
__table_args__ = {"schema": "gn_commons"}
[docs]
id_validation = DB.Column(DB.Integer, primary_key=True)
[docs]
uuid_attached_row = DB.Column(
UUID(as_uuid=True), ForeignKey("gn_synthese.synthese.unique_id_sinp")
)
[docs]
id_nomenclature_valid_status = DB.Column(
DB.Integer,
ForeignKey(TNomenclatures.id_nomenclature),
)
[docs]
nomenclature_valid_status = relationship(
TNomenclatures,
foreign_keys=[id_nomenclature_valid_status],
lazy="joined", # FIXME: remove and manually join when needed
)
[docs]
id_validator = DB.Column(DB.Integer, ForeignKey(User.id_role))
[docs]
validator_role = DB.relationship(User)
[docs]
validation_auto = DB.Column(DB.Boolean)
[docs]
validation_date = DB.Column(DB.TIMESTAMP)
validation_auto = DB.Column(DB.Boolean)
# FIXME: remove and use nomenclature_valid_status
[docs]
validation_label = DB.relationship(
TNomenclatures,
foreign_keys=[id_nomenclature_valid_status],
overlaps="nomenclature_valid_status", # overlaps expected
)
@staticmethod
[docs]
def auto_validation(fct_auto_validation):
stmt = text(
f"""
select routine_name, routine_schema
from information_schema.routines
where routine_name= '{fct_auto_validation}'
and routine_type='FUNCTION';
"""
)
result = DB.session.execute(stmt).fetchall()
if not result:
return
stmt_auto_validation = text(f"SELECT gn_profiles.{fct_auto_validation}()")
DB.session.execute(stmt_auto_validation)
DB.session.commit()
[docs]
last_validation_query = (
select(TValidations)
.order_by(TValidations.validation_date.desc())
.limit(1)
.alias("last_validation")
)
[docs]
last_validation = aliased(TValidations, last_validation_query)
@serializable
@geoserializable
[docs]
class VLatestValidations(DB.Model):
[docs]
__tablename__ = "v_latest_validation"
[docs]
__table_args__ = {"schema": "gn_commons"}
[docs]
id_validation = DB.Column(DB.Integer, primary_key=True)
[docs]
uuid_attached_row = DB.Column(UUID(as_uuid=True))
[docs]
id_nomenclature_valid_status = DB.Column(DB.Integer)
[docs]
id_validator = DB.Column(DB.Integer)
[docs]
validation_date = DB.Column(DB.DateTime)
@serializable
[docs]
class THistoryActions(DB.Model):
[docs]
__tablename__ = "t_history_actions"
[docs]
__table_args__ = {"schema": "gn_commons"}
[docs]
id_history_action = DB.Column(DB.Integer, primary_key=True)
[docs]
id_table_location = DB.Column(DB.Integer)
[docs]
uuid_attached_row = DB.Column(UUID(as_uuid=True))
[docs]
operation_type = DB.Column(DB.Unicode)
[docs]
operation_date = DB.Column(DB.DateTime)
[docs]
table_content = DB.Column(DB.Unicode)
@serializable
[docs]
class TMobileApps(DB.Model):
[docs]
__tablename__ = "t_mobile_apps"
[docs]
__table_args__ = {"schema": "gn_commons"}
[docs]
id_mobile_app = DB.Column(DB.Integer, primary_key=True)
[docs]
app_code = DB.Column(DB.Unicode)
[docs]
relative_path_apk = DB.Column(DB.Unicode)
[docs]
url_apk = DB.Column(DB.Unicode)
[docs]
url_settings = DB.Column(DB.Unicode)
[docs]
package = DB.Column(DB.Unicode)
[docs]
version_code = DB.Column(DB.Unicode)
@serializable
@geoserializable(geoCol="place_geom", idCol="id_place")
[docs]
class TPlaces(DB.Model):
[docs]
__tablename__ = "t_places"
[docs]
__table_args__ = {"schema": "gn_commons"}
[docs]
id_place = DB.Column(DB.Integer, primary_key=True)
[docs]
id_role = DB.Column(DB.Integer, ForeignKey("utilisateurs.t_roles.id_role"))
[docs]
role = relationship(User)
[docs]
place_name = DB.Column(DB.String)
[docs]
place_geom = DB.Column(Geometry("GEOMETRY", 4326))
@serializable
[docs]
cor_field_object = DB.Table(
"cor_field_object",
DB.Column("id_field", DB.Integer, DB.ForeignKey("gn_commons.t_additional_fields.id_field")),
DB.Column("id_object", DB.Integer, DB.ForeignKey("gn_permissions.t_objects.id_object")),
schema="gn_commons",
)
[docs]
cor_field_module = DB.Table(
"cor_field_module",
DB.Column("id_field", DB.Integer, DB.ForeignKey("gn_commons.t_additional_fields.id_field")),
DB.Column("id_module", DB.Integer, DB.ForeignKey("gn_commons.t_modules.id_module")),
schema="gn_commons",
)
[docs]
cor_field_dataset = DB.Table(
"cor_field_dataset",
DB.Column("id_field", DB.Integer, DB.ForeignKey("gn_commons.t_additional_fields.id_field")),
DB.Column("id_dataset", DB.Integer, DB.ForeignKey("gn_meta.t_datasets.id_dataset")),
schema="gn_commons",
)