From dd3005155781b05b4b3c48432c37ade05dc5e1c8 Mon Sep 17 00:00:00 2001 From: Julien Corny Date: Wed, 3 Apr 2024 10:15:07 +0200 Subject: [PATCH 01/10] feat: update to sqlalchemy1.4 --- backend/gn_module_zh/blueprint.py | 137 ++++---- backend/gn_module_zh/forms.py | 308 +++++++++------- backend/gn_module_zh/geometry.py | 77 ++-- backend/gn_module_zh/hierarchy.py | 387 +++++++++++---------- backend/gn_module_zh/model/cards.py | 113 +++--- backend/gn_module_zh/model/code.py | 23 +- backend/gn_module_zh/model/repositories.py | 3 +- backend/gn_module_zh/model/zh.py | 36 +- backend/gn_module_zh/model/zh_schema.py | 240 +++++++------ backend/gn_module_zh/nomenclatures.py | 124 ++++--- backend/gn_module_zh/search.py | 94 ++--- backend/gn_module_zh/upload.py | 8 +- backend/gn_module_zh/utils.py | 44 ++- 13 files changed, 881 insertions(+), 713 deletions(-) diff --git a/backend/gn_module_zh/blueprint.py b/backend/gn_module_zh/blueprint.py index 18a6b3c2..153e775c 100644 --- a/backend/gn_module_zh/blueprint.py +++ b/backend/gn_module_zh/blueprint.py @@ -21,7 +21,7 @@ from geonature.utils.env import DB, ROOT_DIR, BACKEND_DIR from pypnnomenclature.models import TNomenclatures from pypnusershub.db.models import Organisme, User -from sqlalchemy import desc, func, text +from sqlalchemy import desc, func, text, select, update, delete from sqlalchemy.orm import aliased from utils_flask_sqla.generic import GenericQuery from utils_flask_sqla.response import json_resp_accept_empty_list, json_resp @@ -93,7 +93,7 @@ def get_zh(scope): coauthor = aliased(User, name="coauthor") coorganism = aliased(Organisme, name="coorganism") q = ( - DB.session.query(TZH) + select(TZH) .join(TNomenclatures, TZH.sdage) .join(User, TZH.authors) .join(coauthor, TZH.coauthors) @@ -109,6 +109,7 @@ def get_zh(scope): if request.is_json: q = main_search(q, request.json) + # q2 = main_search(q2, request.json) return get_all_zh( info_role=g.current_user, @@ -123,7 +124,9 @@ def get_zh(scope): def get_all_zh(info_role, query, limit, page, orderby=None, order="asc"): # try: # Pour obtenir le nombre de résultat de la requete sans le LIMIT - nb_results_without_limit = query.count() + nb_results_without_limit = ( + DB.session.execute(select(func.count()).select_from(query.subquery())).scalars().one() + ) user = info_role user_cruved = get_user_cruved() @@ -151,7 +154,11 @@ def get_all_zh(info_role, query, limit, page, orderby=None, order="asc"): # Order by id because there can be ambiguity in order_by(col) depending # on the column so add on order_by id makes it clearer - data = query.order_by(TZH.id_zh).limit(limit).offset(page * limit).all() + data = ( + DB.session.execute(query.order_by(TZH.id_zh).limit(limit).offset(page * limit)) + .scalars() + .all() + ) is_ref_geo = check_ref_geo_schema() featureCollection = [] @@ -336,8 +343,7 @@ def get_pbf(): SELECT ST_AsGeobuf(q, 'geom') as pbf FROM (SELECT id_zh, geom from pr_zh.t_zh tz) AS q; """ - query = DB.session.execute(sql) - row = query.first() + row = DB.session.execute(sql).first() return Response(bytes(row["pbf"]) if row["pbf"] else bytes(), mimetype="application/protobuf") @@ -364,8 +370,7 @@ def get_pbf_complete(): 'bassin_versant', tz.bassin_versant) as json_arrays FROM pr_zh.atlas_app tz) AS q; """ - query = DB.session.execute(sql) - row = query.first() + row = DB.session.execute(sql).first() return Response(bytes(row["pbf"]) if row["pbf"] else bytes(), mimetype="application/protobuf") @@ -385,8 +390,7 @@ def get_json(): ) AS feature FROM (SELECT * FROM pr_zh.atlas_app tz) inputs) features; """ - query = DB.session.execute(sql) - row = query.first() + row = DB.session.execute(sql).first() return row["geojson"] @@ -396,7 +400,7 @@ def get_json(): def get_geometries(): """Get list of all zh geometries (contours)""" try: - if not DB.session.query(TZH).all(): + if not DB.session.execute(select(TZH)).all(): raise ZHApiError( message="no_geometry", details="Empty list of zh returned from get_zh_list db request", @@ -406,7 +410,7 @@ def get_geometries(): "geometry": zh.get_geofeature()["geometry"], "id_zh": zh.get_geofeature()["properties"]["id_zh"], } - for zh in DB.session.query(TZH).all() + for zh in DB.session.scalars(select(TZH)).all() ] except Exception as e: if e.__class__.__name__ == "ZHApiError": @@ -428,17 +432,14 @@ def get_ref_autocomplete(): params = request.args search_title = params.get("search_title") # search_title = 'MCD' - q = DB.session.query( - TReferences, - func.similarity(TReferences.title, search_title).label("idx_trgm"), - ) + q = select(TReferences, func.similarity(TReferences.title, search_title).label("idx_trgm")) search_title = search_title.replace(" ", "%") - q = q.filter(TReferences.title.ilike("%" + search_title + "%")).order_by(desc("idx_trgm")) + q = q.where(TReferences.title.ilike("%" + search_title + "%")).order_by(desc("idx_trgm")) limit = request.args.get("limit", 20) - data = q.limit(limit).all() + data = DB.session.execute(q.limit(limit)).all() if data: return [d[0].as_dict() for d in data] else: @@ -462,17 +463,16 @@ def get_file_list(id_zh): """get a list of the zh files contained in static repo""" try: # FIXME: to optimize... See relationships and lazy join with sqlalchemy - zh_uuid = DB.session.query(TZH).filter(TZH.id_zh == id_zh).one().zh_uuid - q_medias = ( - DB.session.query(TMedias, TNomenclatures.label_default) - .filter(TMedias.unique_id_media == zh_uuid) + zh_uuid = DB.session.execute(select(TZH).where(TZH.id_zh == id_zh)).scalar_one().zh_uuid + q_medias = DB.session.execute( + select(TMedias, TNomenclatures.label_default) .join( TNomenclatures, TNomenclatures.id_nomenclature == TMedias.id_nomenclature_media_type, ) + .where(TMedias.unique_id_media == zh_uuid) .order_by(TMedias.meta_update_date.desc()) - .all() - ) + ).all() res_media, image_medias = [], [] for media, media_type in q_medias: res_media.append(media) @@ -528,9 +528,12 @@ def post_main_pict(id_zh, id_media): """post main picture id in tzh""" try: # FIXME: after insert+after update on t_zh => update_date=dt.now() - DB.session.query(TZH).filter(TZH.id_zh == id_zh).update( - {TZH.main_pict_id: id_media, TZH.update_date: dt.now()} + stmt = ( + update(TZH) + .where(TZH.id_zh == id_zh) + .values(main_pict_id=id_media, update_date=dt.now()) ) + DB.session.execute(stmt) DB.session.commit() return ("", 204) except Exception as e: @@ -553,18 +556,17 @@ def post_main_pict(id_zh, id_media): @blueprint.route("/photos", methods=["GET"]) @json_resp def get_all_photos(id_zh: int): - q_medias = ( - DB.session.query(TZH.main_pict_id, TMedias.id_media, TMedias.media_path) + q_medias = DB.session.execute( + select(TZH.main_pict_id, TMedias.id_media, TMedias.media_path) .join(TZH, TZH.zh_uuid == TMedias.unique_id_media) .join( TNomenclatures, TNomenclatures.id_nomenclature == TMedias.id_nomenclature_media_type, ) .order_by(TMedias.meta_update_date.desc()) - .filter(TNomenclatures.label_default == "Photo") - .filter(TZH.id_zh == id_zh) - .all() - ) + .where(TNomenclatures.label_default == "Photo") + .where(TZH.id_zh == id_zh) + ).all() api_uri = urljoin( f"{config['API_ENDPOINT']}/", f"{blueprint.config['MODULE_CODE'].lower()}/{blueprint.config['file_path']}/", @@ -767,18 +769,20 @@ def deleteOneZh(id_zh): zhRepository = ZhRepository(TZH) # delete references - DB.session.query(CorZhRef).filter(CorZhRef.id_zh == id_zh).delete() + DB.session.execute(delete(CorZhRef).where(CorZhRef.id_zh == id_zh)) # delete criteres delim - id_lim_list = DB.session.query(TZH).filter(TZH.id_zh == id_zh).one().id_lim_list - DB.session.query(CorLimList).filter(CorLimList.id_lim_list == id_lim_list).delete() + id_lim_list = ( + DB.session.execute(select(TZH).where(TZH.id_zh == id_zh)).scalar_one().id_lim_list + ) + DB.session.execute(delete(CorLimList).where(CorLimList.id_lim_list == id_lim_list)) # delete cor_zh_area - DB.session.query(CorZhArea).filter(CorZhArea.id_zh == id_zh).delete() + DB.session.execute(delete(CorZhArea).where(CorZhArea.id_zh == id_zh)) # delete files in TMedias and repos - zh_uuid = DB.session.query(TZH).filter(TZH.id_zh == id_zh).one().zh_uuid - q_medias = DB.session.query(TMedias).filter(TMedias.unique_id_media == zh_uuid).all() + zh_uuid = DB.session.execute(select(TZH).where(TZH.id_zh == id_zh)).scalar_one().zh_uuid + q_medias = DB.session.scalars(select(TMedias).where(TMedias.unique_id_media == zh_uuid)).all() for media in q_medias: delete_file(media.id_media) @@ -803,9 +807,11 @@ def write_csv(id_zh): names = [] FILE_PATH = blueprint.config["file_path"] MODULE_NAME = blueprint.config["MODULE_CODE"].lower() - zh_code = DB.session.query(TZH).filter(TZH.id_zh == id_zh).one().code + zh_code = DB.session.execute(select(TZH).where(TZH.id_zh == id_zh)).scalar_one().code # author name - user = DB.session.query(User).filter(User.id_role == g.current_user.id_role).one() + user = DB.session.execute( + select(User).where(User.id_role == g.current_user.id_role) + ).scalar_one() author = user.prenom_role + " " + user.nom_role for i in ["vertebrates_view_name", "invertebrates_view_name", "flora_view_name"]: query = GenericQuery( @@ -813,7 +819,7 @@ def write_csv(id_zh): tableName=blueprint.config[i]["table_name"], schemaName=blueprint.config[i]["schema_name"], filters={"id_zh": id_zh, "orderby": "id_zh"}, - limit=-1, + limit=100, ) results = query.return_query().get("items", []) current_date = dt.now() @@ -864,8 +870,10 @@ def write_csv(id_zh): DB.session.flush() # update TMedias.media_path with media_filename - DB.session.query(TMedias).filter(TMedias.id_media == id_media).update( - {"media_path": str(media_path)} + DB.session.execute( + update(TMedias) + .where(TMedias.id_media == id_media) + .values(media_path=str(media_path)) ) DB.session.commit() @@ -924,41 +932,47 @@ def download(id_zh: int): @json_resp def departments(): query = ( - DB.session.query(LAreas) - .with_entities(LAreas.area_name, LAreas.area_code, LAreas.id_type, BibAreasTypes.type_code) + select(LAreas) + .with_only_columns( + LAreas.area_name, LAreas.area_code, LAreas.id_type, BibAreasTypes.type_code + ) .join(BibAreasTypes, LAreas.id_type == BibAreasTypes.id_type) - .filter(BibAreasTypes.type_code == "DEP") - .filter(LAreas.enable) + .where(BibAreasTypes.type_code == "DEP") + .where(LAreas.enable) .order_by(LAreas.area_code) ) - resp = query.all() + resp = DB.session.execute(query).all() return [{"code": r.area_code, "name": r.area_name} for r in resp] @blueprint.route("/communes", methods=["POST"]) @json_resp def get_area_from_department() -> dict: + # route utilisée ? code = request.json.get("code") if code: query = ( - DB.session.query(LiMunicipalities) - .with_entities(LiMunicipalities.id_area, LAreas.area_name, LAreas.area_code) + select(LiMunicipalities) + .with_only_columns(LiMunicipalities.id_area, LAreas.area_name, LAreas.area_code) .join(LAreas, LiMunicipalities.id_area == LAreas.id_area) - .filter(LiMunicipalities.insee_com.like("{}%".format(code))) - .filter(LAreas.enable) + .where(LiMunicipalities.insee_com.like("{}%".format(code))) + .where(LAreas.enable) + .order_by(LAreas.area_code) ) - query = query.order_by(LAreas.area_code) - resp = query.all() + resp = DB.session.execute(query).all() return [{"code": r.area_code, "name": r.area_name} for r in resp] - return [] @blueprint.route("/bassins", methods=["GET"]) @json_resp def bassins(): - query = DB.session.query(TRiverBasin).with_entities(TRiverBasin.id_rb, TRiverBasin.name) - resp = query.order_by(TRiverBasin.name).all() + query = ( + select(TRiverBasin) + .with_only_columns(TRiverBasin.id_rb, TRiverBasin.name) + .order_by(TRiverBasin.name) + ) + resp = DB.session.execute(query).all() return [{"code": r.id_rb, "name": r.name} for r in resp] @@ -968,9 +982,9 @@ def get_hydro_zones_from_bassin() -> dict: code = request.json.get("code") if code: query = ( - DB.session.query(THydroArea) - .with_entities(THydroArea.id_hydro, THydroArea.name, TRiverBasin.id_rb) - .filter(TRiverBasin.id_rb == code) + select(THydroArea) + .with_only_columns(THydroArea.id_hydro, THydroArea.name, TRiverBasin.id_rb) + .where(TRiverBasin.id_rb == code) .join( TRiverBasin, func.ST_Contains( @@ -978,9 +992,10 @@ def get_hydro_zones_from_bassin() -> dict: func.ST_SetSRID(THydroArea.geom, 4326), ), ) + .order_by(THydroArea.name) ) - resp = query.order_by(THydroArea.name).all() + resp = DB.session.execute(query).all() return [{"code": r.id_hydro, "name": r.name} for r in resp] return [] diff --git a/backend/gn_module_zh/forms.py b/backend/gn_module_zh/forms.py index 560081a8..ec8b7342 100644 --- a/backend/gn_module_zh/forms.py +++ b/backend/gn_module_zh/forms.py @@ -9,6 +9,7 @@ from geonature.utils.env import DB from pypnnomenclature.models import TNomenclatures from sqlalchemy import and_, func +from sqlalchemy.sql import select, delete, update from .api_error import ZHApiError from .model.code import Code @@ -46,7 +47,7 @@ def update_tzh(data): - zh = DB.session.query(TZH).filter_by(id_zh=data["id_zh"]).first() + zh = DB.session.get(TZH, data["id_zh"]) for key, val in data.items(): if hasattr(TZH, key) and key != "id_zh": setattr(zh, key, val) @@ -85,22 +86,27 @@ def create_zh(form_data, info_role, zh_date, polygon, zh_area, ref_geo_referenti post_cor_zh_area( polygon, new_zh.id_zh, - DB.session.query(BibAreasTypes).filter(BibAreasTypes.type_code == "COM").one().id_type, + DB.session.execute(select(BibAreasTypes).where(BibAreasTypes.type_code == "COM")) + .scalar_one() + .id_type, ) # fill cor_zh_area for departements post_cor_zh_area( polygon, new_zh.id_zh, - DB.session.query(BibAreasTypes).filter(BibAreasTypes.type_code == "DEP").one().id_type, + DB.session.execute(select(BibAreasTypes).where(BibAreasTypes.type_code == "DEP")) + .scalar_one() + .id_type, ) # fill cor_zh_area for other geo referentials for ref in ref_geo_referentiels: post_cor_zh_area( polygon, new_zh.id_zh, - DB.session.query(BibAreasTypes) - .filter(BibAreasTypes.type_code == ref["type_code_ref_geo"]) - .one() + DB.session.execute( + select(BibAreasTypes).where(BibAreasTypes.type_code == ref["type_code_ref_geo"]) + ) + .scalar_one() .id_type, ) @@ -116,9 +122,12 @@ def create_zh(form_data, info_role, zh_date, polygon, zh_area, ref_geo_referenti new_zh.ef_area = total_cover # set default values fct_delim_default_id = ( - DB.session.query(DefaultsNomenclaturesValues) - .filter(DefaultsNomenclaturesValues.mnemonique_type == "CRIT_DEF_ESP_FCT") - .one() + DB.session.execute( + select(DefaultsNomenclaturesValues).where( + DefaultsNomenclaturesValues.mnemonique_type == "CRIT_DEF_ESP_FCT" + ) + ) + .scalar_one() .id_nomenclature ) @@ -168,28 +177,27 @@ def post_cor_zh_area(polygon, id_zh, id_type): # try: elements = [ getattr(element, "id_area") - for element in DB.session.query(LAreas) - .filter( - LAreas.geom.ST_Intersects( - func.ST_Transform(func.ST_SetSRID(func.ST_AsText(polygon), 4326), 2154) + for element in DB.session.scalars( + select(LAreas) + .where( + LAreas.geom.ST_Intersects( + func.ST_Transform(func.ST_SetSRID(func.ST_AsText(polygon), 4326), 2154) + ) ) - ) - .filter(LAreas.id_type == id_type) - .all() + .where(LAreas.id_type == id_type) + ).all() ] for element in elements: # if 'Communes', % of zh in the municipality must be calculated if id_type == CorZhArea.get_id_type("Communes"): - municipality_geom = getattr( - DB.session.query(LAreas).filter(LAreas.id_area == element).first(), "geom" + municipality_geom = getattr(DB.session.get(LAreas, element), "geom") + polygon_2154 = DB.session.scalar( + select(func.ST_Transform(func.ST_SetSRID(func.ST_AsText(polygon), 4326), 2154)) ) - polygon_2154 = DB.session.query( - func.ST_Transform(func.ST_SetSRID(func.ST_AsText(polygon), 4326), 2154) - ).scalar() - intersect_area = DB.session.query( - func.ST_Area(func.ST_Intersection(municipality_geom, polygon_2154)) - ).scalar() - municipality_area = DB.session.query(func.ST_Area(municipality_geom)).scalar() + intersect_area = DB.session.scalar( + select(func.ST_Area(func.ST_Intersection(municipality_geom, polygon_2154))) + ) + municipality_area = DB.session.scalar(select(func.ST_Area(municipality_geom))) cover = math.ceil((intersect_area * 100) / municipality_area) if cover > 100: cover = 100 @@ -280,11 +288,10 @@ def update_zh_tab0(form_data, polygon, area, info_role, zh_date, geo_refs): is_geom_new = check_polygon(polygon, form_data["id_zh"]) # update pr_zh.cor_lim_list - id_lim_list, ef_area = ( - DB.session.query(TZH.id_lim_list, TZH.ef_area).filter(TZH.id_zh == form_data["id_zh"]).one() - ) + id_lim_list = DB.session.get(TZH, form_data["id_zh"]).id_lim_list + ef_area = DB.session.get(TZH, form_data["id_zh"]).ef_area - DB.session.query(CorLimList).filter(CorLimList.id_lim_list == id_lim_list).delete() + DB.session.execute(delete(CorLimList).where(CorLimList.id_lim_list == id_lim_list)) post_cor_lim_list(id_lim_list, form_data["critere_delim"]) if is_geom_new: @@ -294,17 +301,19 @@ def update_zh_tab0(form_data, polygon, area, info_role, zh_date, geo_refs): ef_area = update_cor_zh_fct_area(form_data["geom"]["geometry"], form_data["id_zh"]) # update zh : fill pr_zh.t_zh - DB.session.query(TZH).filter(TZH.id_zh == form_data["id_zh"]).update( - { - TZH.main_name: form_data["main_name"], - TZH.id_org: form_data["id_org"], - TZH.update_author: info_role.id_role, - TZH.update_date: zh_date, - TZH.id_sdage: form_data["sdage"], - TZH.geom: polygon, - TZH.area: area, - TZH.ef_area: ef_area, - } + DB.session.execute( + update(TZH) + .where(TZH.id_zh == form_data["id_zh"]) + .values( + main_name=form_data["main_name"], + id_org=form_data["id_org"], + update_author=info_role.id_role, + update_date=zh_date, + id_sdage=form_data["sdage"], + geom=polygon, + area=area, + ef_area=ef_area, + ) ) DB.session.flush() @@ -324,7 +333,12 @@ def update_zh_tab0(form_data, polygon, area, info_role, zh_date, geo_refs): def check_polygon(polygon, id_zh): try: - if polygon != str(DB.session.query(TZH.geom).filter(TZH.id_zh == id_zh).one()[0]).upper(): + if ( + polygon + != str( + DB.session.execute(select(TZH.geom).where(TZH.id_zh == id_zh)).scalar_one() + ).upper() + ): return True return False except Exception as e: @@ -336,25 +350,32 @@ def check_polygon(polygon, id_zh): def update_cor_zh_area(polygon, id_zh, geo_refs): try: - DB.session.query(CorZhArea).filter(CorZhArea.id_zh == id_zh).delete() + DB.session.execute(delete(CorZhArea).where(CorZhArea.id_zh == id_zh)) post_cor_zh_area( polygon, id_zh, - DB.session.query(BibAreasTypes).filter(BibAreasTypes.type_code == "COM").one().id_type, + DB.session.execute(select(BibAreasTypes).where(BibAreasTypes.type_code == "COM")) + .scalar_one() + .id_type, ) post_cor_zh_area( polygon, id_zh, - DB.session.query(BibAreasTypes).filter(BibAreasTypes.type_code == "DEP").one().id_type, + DB.session.execute(select(BibAreasTypes).where(BibAreasTypes.type_code == "DEP")) + .scalar_one() + .id_type, ) # fill cor_zh_area for other geo referentials for ref in geo_refs: post_cor_zh_area( polygon, id_zh, - DB.session.query(BibAreasTypes) - .filter(BibAreasTypes.type_code == ref["type_code_ref_geo"]) - .one() + DB.session.execute( + select(BibAreasTypes).where( + BibAreasTypes.type_code == ref["type_code_ref_geo"] + ) + ) + .scalar_one() .id_type, ) except Exception as e: @@ -372,17 +393,17 @@ def update_cor_zh_area(polygon, id_zh, geo_refs): def update_cor_zh_rb(geom, id_zh): - DB.session.query(CorZhRb).filter(CorZhRb.id_zh == id_zh).delete() + DB.session.execute(delete(CorZhRb).where(CorZhRb.id_zh == id_zh)) post_cor_zh_rb(geom, id_zh) def update_cor_zh_hydro(geom, id_zh): - DB.session.query(CorZhHydro).filter(CorZhHydro.id_zh == id_zh).delete() + DB.session.execute(delete(CorZhHydro).where(CorZhHydro.id_zh == id_zh)) post_cor_zh_hydro(geom, id_zh) def update_cor_zh_fct_area(geom, id_zh): - DB.session.query(CorZhFctArea).filter(CorZhFctArea.id_zh == id_zh).delete() + DB.session.execute(delete(CorZhFctArea).where(CorZhFctArea.id_zh == id_zh)) return post_cor_zh_fct_area(geom, id_zh) @@ -391,7 +412,7 @@ def update_cor_zh_fct_area(geom, id_zh): def update_refs(form_data): try: - DB.session.query(CorZhRef).filter(CorZhRef.id_zh == form_data["id_zh"]).delete() + DB.session.execute(delete(CorZhRef).where(CorZhRef.id_zh == form_data["id_zh"])) for ref in form_data["id_references"]: DB.session.add(CorZhRef(id_zh=form_data["id_zh"], id_ref=ref)) DB.session.flush() @@ -436,7 +457,7 @@ def post_activities(id_zh, activities): def update_activities(id_zh, activities): try: # delete cascade t_activity and cor_impact_list with id_zh - DB.session.query(TActivity).filter(TActivity.id_zh == id_zh).delete() + DB.session.execute(delete(TActivity).where(TActivity.id_zh == id_zh)) # post new activities post_activities(id_zh, activities) except Exception as e: @@ -455,7 +476,7 @@ def update_activities(id_zh, activities): def update_corine_biotopes(id_zh, corine_biotopes): try: - DB.session.query(CorZhCb).filter(CorZhCb.id_zh == id_zh).delete() + DB.session.execute(delete(CorZhCb).where(CorZhCb.id_zh == id_zh)) post_corine_biotopes(id_zh, corine_biotopes) except Exception as e: if e.__class__.__name__ == "DataError": @@ -479,7 +500,7 @@ def post_corine_biotopes(id_zh, corine_biotopes): def update_corine_landcover(id_zh, ids_cover): try: - DB.session.query(CorZhCorineCover).filter(CorZhCorineCover.id_zh == id_zh).delete() + DB.session.execute(delete(CorZhCorineCover).where(CorZhCorineCover.id_zh == id_zh)) post_corine_landcover(id_zh, ids_cover) except Exception as e: if e.__class__.__name__ == "DataError": @@ -506,10 +527,8 @@ def post_corine_landcover(id_zh, ids_cover): def update_delim(id_zh, criteria): try: - uuid_lim_list = ( - DB.session.query(TZH.id_lim_list).filter(TZH.id_zh == id_zh).one().id_lim_list - ) - DB.session.query(CorLimList).filter(CorLimList.id_lim_list == uuid_lim_list).delete() + uuid_lim_list = DB.session.get(TZH, id_zh).id_lim_list + DB.session.execute(delete(CorLimList).where(CorLimList.id_lim_list == uuid_lim_list)) post_delim(uuid_lim_list, criteria) except Exception as e: if e.__class__.__name__ == "DataError": @@ -533,7 +552,7 @@ def post_delim(uuid_lim, criteria): def update_fct_delim(id_zh, criteria): try: - DB.session.query(CorZhLimFs).filter(CorZhLimFs.id_zh == id_zh).delete() + DB.session.execute(delete(CorZhLimFs).where(CorZhLimFs.id_zh == id_zh)) post_fct_delim(id_zh, criteria) except Exception as e: if e.__class__.__name__ == "DataError": @@ -560,7 +579,7 @@ def post_fct_delim(id_zh, criteria): def update_outflow(id_zh, outflows): try: - DB.session.query(TOutflow).filter(TOutflow.id_zh == id_zh).delete() + DB.session.execute(delete(TOutflow).where(TOutflow.id_zh == id_zh)) post_outflow(id_zh, outflows) except Exception as e: if e.__class__.__name__ == "DataError": @@ -591,7 +610,7 @@ def post_outflow(id_zh, outflows): def update_inflow(id_zh, inflows): try: - DB.session.query(TInflow).filter(TInflow.id_zh == id_zh).delete() + DB.session.execute(select(TInflow).where(TInflow.id_zh == id_zh)) post_inflow(id_zh, inflows) except Exception as e: if e.__class__.__name__ == "DataError": @@ -643,9 +662,13 @@ def update_functions(id_zh, functions, function_type): nomenclature.id_nomenclature for nomenclature in Nomenclatures.get_nomenclature_info(function_type) ] - DB.session.query(TFunctions).filter(TFunctions.id_zh == id_zh).filter( - TFunctions.id_function.in_(id_function_list) - ).delete(synchronize_session="fetch") + stmt = ( + delete(TFunctions) + .where(TFunctions.id_zh == id_zh) + .where(TFunctions.id_function.in_(id_function_list)) + .execution_options(synchronize_session="fetch") + ) + DB.session.execute(stmt) post_functions(id_zh, functions) except Exception as e: if e.__class__.__name__ == "DataError": @@ -664,7 +687,7 @@ def update_functions(id_zh, functions, function_type): def update_hab_heritages(id_zh, hab_heritages): try: # delete cascade t_hab_heritages - DB.session.query(THabHeritage).filter(THabHeritage.id_zh == id_zh).delete() + DB.session.execute(delete(THabHeritage).where(THabHeritage.id_zh == id_zh)) # post new hab_heritages post_hab_heritages(id_zh, hab_heritages) except Exception as e: @@ -699,7 +722,7 @@ def post_hab_heritages(id_zh, hab_heritages): def update_ownerships(id_zh, ownerships): try: - DB.session.query(TOwnership).filter(TOwnership.id_zh == id_zh).delete() + DB.session.execute(delete(TOwnership).where(TOwnership.id_zh == id_zh)) post_ownerships(id_zh, ownerships) except Exception as e: if e.__class__.__name__ == "DataError": @@ -725,9 +748,9 @@ def post_ownerships(id_zh, ownerships): def update_managements(id_zh, managements): try: - DB.session.query(TManagementStructures).filter( - TManagementStructures.id_zh == id_zh - ).delete() + DB.session.execute( + delete(TManagementStructures).where(TManagementStructures.id_zh == id_zh) + ) # verifier si suppression en cascade ok dans TManagementPlans post_managements(id_zh, managements) except Exception as e: @@ -753,14 +776,15 @@ def post_managements(id_zh, managements): DB.session.add( TManagementPlans( id_nature=plan["id_nature"], - id_structure=DB.session.query(TManagementStructures) - .filter( - and_( - TManagementStructures.id_zh == id_zh, - TManagementStructures.id_org == management["structure"], + id_structure=DB.session.execute( + select(TManagementStructures).where( + and_( + TManagementStructures.id_zh == id_zh, + TManagementStructures.id_org == management["structure"], + ) ) ) - .one() + .scalar_one() .id_structure, plan_date=datetime.datetime.strptime(plan["plan_date"], "%d/%m/%Y"), duration=plan["duration"], @@ -772,7 +796,7 @@ def post_managements(id_zh, managements): def update_instruments(id_zh, instruments): try: - DB.session.query(TInstruments).filter(TInstruments.id_zh == id_zh).delete() + DB.session.execute(delete(TInstruments).where(TInstruments.id_zh == id_zh)) post_instruments(id_zh, instruments) except Exception as e: if e.__class__.__name__ == "DataError": @@ -804,7 +828,7 @@ def post_instruments(id_zh, instruments): def update_protections(id_zh, protections): try: - DB.session.query(CorZhProtection).filter(CorZhProtection.id_zh == id_zh).delete() + DB.session.execute(select(CorZhProtection).where(CorZhProtection.id_zh == id_zh)) post_protections(id_zh, protections) except Exception as e: if e.__class__.__name__ == "DataError": @@ -824,9 +848,12 @@ def post_protections(id_zh, protections): for protection in protections: DB.session.add( CorZhProtection( - id_protection=DB.session.query(CorProtectionLevelType) - .filter(CorProtectionLevelType.id_protection_status == protection) - .one() + id_protection=DB.session.execute( + select(CorProtectionLevelType).where( + CorProtectionLevelType.id_protection_status == protection + ) + ) + .scalar_one() .id_protection, id_zh=id_zh, ) @@ -837,15 +864,17 @@ def post_protections(id_zh, protections): def update_zh_tab6(data): try: is_other_inventory = data["is_other_inventory"] - DB.session.query(TZH).filter(TZH.id_zh == data["id_zh"]).update( - { - TZH.update_author: data["update_author"], - TZH.update_date: data["update_date"], - TZH.is_other_inventory: is_other_inventory, - TZH.remark_is_other_inventory: ( + DB.session.execute( + update(TZH) + .where(TZH.id_zh == data["id_zh"]) + .values( + update_author=data["update_author"], + update_date=data["update_date"], + is_other_inventory=is_other_inventory, + remark_is_other_inventory=( data["remark_is_other_inventory"] if is_other_inventory else None ), - } + ) ) DB.session.flush() except Exception as e: @@ -864,7 +893,7 @@ def update_zh_tab6(data): def update_urban_docs(id_zh, urban_docs): try: - DB.session.query(TUrbanPlanningDocs).filter(TUrbanPlanningDocs.id_zh == id_zh).delete() + DB.session.execute(delete(TUrbanPlanningDocs).where(TUrbanPlanningDocs.id_zh == id_zh)) post_urban_docs(id_zh, urban_docs) except Exception as e: if e.__class__.__name__ == "DataError": @@ -883,9 +912,12 @@ def update_urban_docs(id_zh, urban_docs): def post_urban_docs(id_zh, urban_docs): for urban_doc in urban_docs: id_doc_type = ( - DB.session.query(CorUrbanTypeRange) - .filter(CorUrbanTypeRange.id_cor == urban_doc["id_urban_type"][0]["id_cor"]) - .one() + DB.session.execute( + select(CorUrbanTypeRange).where( + CorUrbanTypeRange.id_cor == urban_doc["id_urban_type"][0]["id_cor"] + ) + ) + .scalar_one() .id_doc_type ) uuid_doc = uuid.uuid4() @@ -910,7 +942,7 @@ def post_urban_docs(id_zh, urban_docs): def update_actions(id_zh, actions): try: # delete cascade actions - DB.session.query(TActions).filter(TActions.id_zh == id_zh).delete() + DB.session.execute(select(TActions).where(TActions.id_zh == id_zh)) # post new actions post_actions(id_zh, actions) except Exception as e: @@ -945,7 +977,9 @@ def post_actions(id_zh, actions): def post_file_info(id_zh, title, author, description, extension, media_path=None): try: - unique_id_media = DB.session.query(TZH).filter(TZH.id_zh == int(id_zh)).one().zh_uuid + unique_id_media = ( + DB.session.execute(select(TZH).where(TZH.id_zh == int(id_zh))).scalar_one().zh_uuid + ) uuid_attached_row = uuid.uuid4() if extension == ".pdf": mnemo = "PDF" @@ -954,20 +988,20 @@ def post_file_info(id_zh, title, author, description, extension, media_path=None else: mnemo = "Photo" id_nomenclature_media_type = ( - DB.session.query(TNomenclatures) - .filter(TNomenclatures.mnemonique == mnemo) - .one() + DB.session.execute(select(TNomenclatures).where(TNomenclatures.mnemonique == mnemo)) + .scalar_one() .id_nomenclature ) id_table_location = ( - DB.session.query(BibTablesLocation) - .filter( - and_( - BibTablesLocation.schema_name == "pr_zh", - BibTablesLocation.table_name == "t_zh", + DB.session.execute( + select(BibTablesLocation).where( + and_( + BibTablesLocation.schema_name == "pr_zh", + BibTablesLocation.table_name == "t_zh", + ) ) ) - .one() + .scalar_one() .id_table_location ) post_date = datetime.datetime.now() @@ -988,9 +1022,10 @@ def post_file_info(id_zh, title, author, description, extension, media_path=None ) DB.session.commit() id_media = ( - DB.session.query(TMedias) - .filter(TMedias.uuid_attached_row == uuid_attached_row) - .one() + DB.session.execute( + select(TMedias).where(TMedias.uuid_attached_row == uuid_attached_row) + ) + .scalar_one() .id_media ) return id_media @@ -1006,31 +1041,36 @@ def post_file_info(id_zh, title, author, description, extension, media_path=None def patch_file_info(id_zh, id_media, title, author, description): try: - unique_id_media = DB.session.query(TZH).filter(TZH.id_zh == int(id_zh)).one().zh_uuid + unique_id_media = ( + DB.session.execute(select(TZH).where(TZH.id_zh == int(id_zh))).scalar_one().zh_uuid + ) uuid_attached_row = uuid.uuid4() id_table_location = ( - DB.session.query(BibTablesLocation) - .filter( - and_( - BibTablesLocation.schema_name == "pr_zh", - BibTablesLocation.table_name == "t_zh", + DB.session.execute( + select(BibTablesLocation).where( + and_( + BibTablesLocation.schema_name == "pr_zh", + BibTablesLocation.table_name == "t_zh", + ) ) ) - .one() + .scalar_one() .id_table_location ) post_date = datetime.datetime.now() - DB.session.query(TMedias).filter(TMedias.id_media == id_media).update( - { - "unique_id_media": unique_id_media, - "id_table_location": id_table_location, - "uuid_attached_row": uuid_attached_row, - "title_fr": title, - "author": author, - "description_fr": description, - "is_public": True, - "meta_update_date": str(post_date), - } + DB.session.execute( + update(TMedias) + .where(TMedias.id_media == id_media) + .values( + unique_id_media=unique_id_media, + id_table_location=id_table_location, + uuid_attached_row=uuid_attached_row, + title_fr=title, + author=author, + description_fr=description, + is_public=True, + meta_update_date=str(post_date), + ) ) DB.session.flush() except exc.DataError as e: @@ -1052,13 +1092,14 @@ def update_file_extension(id_media, extension): else: mnemo = "Photo" id_nomenclature_media_type = ( - DB.session.query(TNomenclatures) - .filter(TNomenclatures.mnemonique == mnemo) - .one() + DB.session.execute(select(TNomenclatures).where(TNomenclatures.mnemonique == mnemo)) + .scalar_one() .id_nomenclature ) - DB.session.query(TMedias).filter(TMedias.id_media == id_media).update( - {"id_nomenclature_media_type": id_nomenclature_media_type} + DB.session.execute( + update(TMedias) + .where(TMedias.id_media == id_media) + .values(id_nomenclature_media_type=id_nomenclature_media_type) ) DB.session.flush() except exc.DataError as e: @@ -1073,12 +1114,11 @@ def update_file_extension(id_media, extension): def post_note(id_zh, cor_rule_id, note, attribute_id, note_type_id): try: - element = ( - DB.session.query(CorZhNotes) - .filter(CorZhNotes.id_zh == id_zh) - .filter(CorZhNotes.cor_rule_id == cor_rule_id) - .first() - ) + element = DB.session.scalars( + select(CorZhNotes) + .where(CorZhNotes.id_zh == id_zh) + .where(CorZhNotes.cor_rule_id == cor_rule_id) + ).first() if element: if element.note != note: element.note = note diff --git a/backend/gn_module_zh/geometry.py b/backend/gn_module_zh/geometry.py index b9429a5f..3742036a 100644 --- a/backend/gn_module_zh/geometry.py +++ b/backend/gn_module_zh/geometry.py @@ -2,7 +2,7 @@ from geoalchemy2.shape import to_shape from geonature.utils.env import DB -from sqlalchemy import func +from sqlalchemy.sql import select, func from werkzeug.exceptions import BadRequest from .api_error import ZHApiError @@ -17,45 +17,48 @@ def set_geom(geometry, id_zh=None): # SetSRID for POSTGIS < 3.0 compat # select only already existing ZH geometries which intersect with the new ZH geometry - q_zh = ( - DB.session.query(TZH) - .filter( + # polygon = DB.session.execute( + # select(func.ST_SetSRID(func.ST_GeomFromGeoJSON(str(geometry)), 4326)) + # ).scalar_one() + q_zh = DB.session.scalars( + select(TZH) + .where( func.ST_Intersects( func.ST_GeogFromWKB(func.ST_AsEWKB(TZH.geom)), func.ST_GeogFromWKB(func.ST_AsEWKB(str(geometry))), ) ) - .filter( - func.ST_Touches( + .where(func.ST_Touches( func.ST_GeomFromWKB(func.ST_AsEWKB(TZH.geom), 4326), func.ST_GeomFromWKB(func.ST_AsEWKB(str(geometry)), 4326), ) == False ) - .all() - ) + ).all() + is_intersected = False for zh in q_zh: if zh.id_zh != id_zh: - zh_geom = DB.session.query(func.ST_GeogFromWKB(func.ST_AsEWKB(zh.geom))).scalar() - polygon_geom = DB.session.query( - func.ST_GeogFromWKB(func.ST_AsEWKB(str(geometry))) - ).scalar() - if DB.session.query(func.ST_Intersects(polygon_geom, zh_geom)).scalar(): - if DB.session.query( - func.ST_GeometryType(func.ST_Intersection(zh_geom, polygon_geom, 0.1)) - ).scalar() not in ["ST_LineString", "ST_MultiLineString"]: + zh_geom = DB.session.scalar(select(func.ST_GeogFromWKB(func.ST_AsEWKB(zh.geom)))) + polygon_geom = DB.session.scalar( + select(func.ST_GeogFromWKB(func.ST_AsEWKB(str(geometry)))) + ) + if DB.session.scalar(select(func.ST_Intersects(polygon_geom, zh_geom))): + if DB.session.scalar( + func.ST_GeometryType(func.ST_Intersection(zh_geom, polygon_geom, 0.1)) + ) not in ["ST_LineString", "ST_MultiLineString"]: is_intersected = True - if DB.session.query( + if DB.session.scalar( func.ST_Contains( zh_geom, polygon_geom, + ) - ).scalar(): + ): raise BadRequest("La ZH est entièrement dans une ZH existante") - # TODO: not detected if contained entirely in 2 or more ZH polygons - polygon = DB.session.query(func.ST_Difference(polygon_geom, zh_geom)).scalar() + # TODO: not detected if contained entirely in 2 or more ZH polygons + polygon = DB.session.scalar(select(func.ST_Difference(polygon_geom, zh_geom))) return {"polygon": polygon, "is_intersected": is_intersected} @@ -63,9 +66,9 @@ def set_area(geom): # unit : ha return round( ( - DB.session.query( - func.ST_Area(func.ST_GeomFromText(func.ST_AsText(geom["polygon"])), False) - ).scalar() + DB.session.scalar( + select(func.ST_Area(func.ST_GeomFromText(func.ST_AsText(geom["polygon"])), False)) + ) ) / 10000, 2, @@ -77,22 +80,28 @@ def get_main_rb(query: list) -> int: area = 0 for q_ in query: zh_polygon = ( - DB.session.query(TZH.geom).filter(TZH.id_zh == getattr(q_, "id_zh")).first().geom + DB.session.scalars(select(TZH.geom).where(TZH.id_zh == getattr(q_, "id_zh"))) + .first() + .geom ) rb_polygon = ( - DB.session.query(CorZhRb, TRiverBasin) - .join(TRiverBasin, TRiverBasin.id_rb == CorZhRb.id_rb) - .filter(TRiverBasin.id_rb == getattr(q_, "id_rb")) + DB.session.scalar( + select(CorZhRb, TRiverBasin) + .join(TRiverBasin, TRiverBasin.id_rb == CorZhRb.id_rb) + .where(TRiverBasin.id_rb == getattr(q_, "id_rb")) + ) .first() .TRiverBasin.geom ) - intersection = DB.session.query( - func.ST_Intersection( - func.ST_GeomFromText(func.ST_AsText(zh_polygon)), - func.ST_GeomFromText(func.ST_AsText(rb_polygon)), + intersection = DB.session.scalar( + select( + func.ST_Intersection( + func.ST_GeomFromText(func.ST_AsText(zh_polygon)), + func.ST_GeomFromText(func.ST_AsText(rb_polygon)), + ) ) - ).scalar() - if DB.session.query(func.ST_Area(intersection, False)).scalar() > area: - area = DB.session.query(func.ST_Area(intersection, False)).scalar() + ) + if DB.session.scalar(select(func.ST_Area(intersection, False))) > area: + area = DB.session.scalar(select(func.ST_Area(intersection, False))) rb_id = getattr(q_, "id_rb") return rb_id diff --git a/backend/gn_module_zh/hierarchy.py b/backend/gn_module_zh/hierarchy.py index 4cd861dd..e769e321 100644 --- a/backend/gn_module_zh/hierarchy.py +++ b/backend/gn_module_zh/hierarchy.py @@ -6,6 +6,7 @@ from geonature.utils.env import DB from pypnnomenclature.models import BibNomenclaturesTypes, TNomenclatures from sqlalchemy import and_ +from sqlalchemy.sql import select from sqlalchemy.orm.exc import NoResultFound from utils_flask_sqla.generic import GenericQuery @@ -54,7 +55,7 @@ def __init__(self, id_zh, rb_id, abb): def __get_rule_id(self, abb): try: return getattr( - DB.session.query(TRules).filter(TRules.abbreviation == abb).one(), + DB.session.execute(select(TRules).where(TRules.abbreviation == abb)).scalar_one(), "rule_id", ) except Exception as e: @@ -68,16 +69,14 @@ def __get_rule_id(self, abb): def __is_rb_rule(self): try: - q_rule = ( - DB.session.query(CorRbRules) - .filter( + q_rule = DB.session.scalars( + select(CorRbRules).where( and_( CorRbRules.rb_id == self.rb_id, CorRbRules.rule_id == self.rule_id, ) ) - .first() - ) + ).first() if q_rule: return True return False @@ -94,14 +93,14 @@ def __get_cor_rule_id(self): try: if self.active: return getattr( - DB.session.query(CorRbRules) - .filter( - and_( - CorRbRules.rb_id == self.rb_id, - CorRbRules.rule_id == self.rule_id, + DB.session.execute( + select(CorRbRules).where( + and_( + CorRbRules.rb_id == self.rb_id, + CorRbRules.rule_id == self.rule_id, + ) ) - ) - .one(), + ).scalar_one(), "cor_rule_id", ) except Exception as e: @@ -115,14 +114,14 @@ def __get_cor_rule_id(self): def __get_id_nomenc(self, id_type: int, cd_nomenc: str) -> int: return getattr( - DB.session.query(TNomenclatures) - .filter( - and_( - TNomenclatures.id_type == id_type, - TNomenclatures.cd_nomenclature == cd_nomenc, + DB.session.scalars( + select(TNomenclatures).where( + and_( + TNomenclatures.id_type == id_type, + TNomenclatures.cd_nomenclature == cd_nomenc, + ) ) - ) - .first(), + ).first(), "id_nomenclature", None, ) @@ -131,10 +130,11 @@ def __get_nomencs(self, abb, cat=None): cat_id = self.__get_id_nomenc(self.__get_id_type("HIERARCHY"), cat) return [ getattr(q_.CorRuleNomenc, "nomenc_id") - for q_ in DB.session.query(CorRuleNomenc, TRules) - .join(TRules) - .filter(and_(TRules.abbreviation == abb, CorRuleNomenc.qualif_id == cat_id)) - .all() + for q_ in DB.session.execute( + select(CorRuleNomenc, TRules) + .join(TRules) + .where(and_(TRules.abbreviation == abb, CorRuleNomenc.qualif_id == cat_id)) + ).all() ] def __get_nomenc_ids(self): @@ -161,9 +161,9 @@ def __get_qualif_cat7(self): id_nomenc = self.__get_qualif_val() if ( getattr( - DB.session.query(TNomenclatures) - .filter(TNomenclatures.id_nomenclature == id_nomenc) - .one(), + DB.session.execute( + select(TNomenclatures).where(TNomenclatures.id_nomenclature == id_nomenc) + ).scalar_one(), "cd_nomenclature", ) == "0" @@ -171,9 +171,9 @@ def __get_qualif_cat7(self): return self.__get_id_nomenc(self.__get_id_type("HIERARCHY"), "NE") if ( getattr( - DB.session.query(TNomenclatures) - .filter(TNomenclatures.id_nomenclature == id_nomenc) - .one(), + DB.session.execute( + select(TNomenclatures).where(TNomenclatures.id_nomenclature == id_nomenc) + ).scalar_one(), "cd_nomenclature", ) == "1" @@ -181,9 +181,9 @@ def __get_qualif_cat7(self): return self.__get_id_nomenc(self.__get_id_type("HIERARCHY"), "bon") if ( getattr( - DB.session.query(TNomenclatures) - .filter(TNomenclatures.id_nomenclature == id_nomenc) - .one(), + DB.session.execute( + select(TNomenclatures).where(TNomenclatures.id_nomenclature == id_nomenc) + ).scalar_one(), "cd_nomenclature", ) == "2" @@ -191,9 +191,9 @@ def __get_qualif_cat7(self): return self.__get_id_nomenc(self.__get_id_type("HIERARCHY"), "moyen") if ( getattr( - DB.session.query(TNomenclatures) - .filter(TNomenclatures.id_nomenclature == id_nomenc) - .one(), + DB.session.execute( + select(TNomenclatures).where(TNomenclatures.id_nomenclature == id_nomenc) + ).scalar_one(), "cd_nomenclature", ) == "3" @@ -253,24 +253,23 @@ def __get_qualif_heritage(self): if not nb: nb = 0 try: - qualif = ( - DB.session.query(CorRbRules, TItems, CorItemValue) + qualif = DB.session.scalars( + select(CorRbRules, TItems, CorItemValue) .join(TItems, TItems.cor_rule_id == CorRbRules.cor_rule_id) .join(CorItemValue, TItems.attribute_id == CorItemValue.attribute_id) - .filter( + .where( and_( CorRbRules.rb_id == self.rb_id, CorRbRules.rule_id == self.rule_id, ) ) - .filter( + .where( and_( CorItemValue.val_min.__le__(nb), CorItemValue.val_max.__ge__(nb), ) ) - .first() - ) + ).first() except Exception as e: exc_type, value, tb = sys.exc_info() raise ZHApiError( @@ -341,26 +340,26 @@ def __get_qualif_eco(self): if len(q_functions) >= 1: # if 61 and/or 62 : get nomenc id of continum ('res') return getattr( - DB.session.query(TNomenclatures) - .filter( - and_( - TNomenclatures.id_type == hier_type_id, - TNomenclatures.cd_nomenclature == "res", + DB.session.execute( + select(TNomenclatures).where( + and_( + TNomenclatures.id_type == hier_type_id, + TNomenclatures.cd_nomenclature == "res", + ) ) - ) - .one(), + ).scalar_one(), "id_nomenclature", ) else: return getattr( - DB.session.query(TNomenclatures) - .filter( - and_( - TNomenclatures.id_type == hier_type_id, - TNomenclatures.cd_nomenclature == "iso", + DB.session.execute( + select(TNomenclatures).where( + and_( + TNomenclatures.id_type == hier_type_id, + TNomenclatures.cd_nomenclature == "iso", + ) ) - ) - .one(), + ).scalar_one(), "id_nomenclature", ) except ZHApiError as e: @@ -382,17 +381,19 @@ def __get_selected_status(self): try: return [ getattr(q_.TNomenclatures, "id_nomenclature") - for q_ in DB.session.query(CorZhProtection, CorProtectionLevelType, TNomenclatures) - .join( - CorProtectionLevelType, - CorZhProtection.id_protection == CorProtectionLevelType.id_protection, - ) - .join( - TNomenclatures, - TNomenclatures.id_nomenclature == CorProtectionLevelType.id_protection_status, - ) - .filter(CorZhProtection.id_zh == self.id_zh) - .all() + for q_ in DB.session.execute( + select(CorZhProtection, CorProtectionLevelType, TNomenclatures) + .join( + CorProtectionLevelType, + CorZhProtection.id_protection == CorProtectionLevelType.id_protection, + ) + .join( + TNomenclatures, + TNomenclatures.id_nomenclature + == CorProtectionLevelType.id_protection_status, + ) + .where(CorZhProtection.id_zh == self.id_zh) + ).all() ] except ZHApiError as e: raise ZHApiError( @@ -415,16 +416,15 @@ def __get_selected_functions(self, nomenc_ids): # type_id = getattr(DB.session.query(BibNomenclaturesTypes).filter( # BibNomenclaturesTypes.mnemonique == nomenc_type_mnemo).one(), 'id_type') # get selected functions - q_ = ( - DB.session.query(TFunctions, TNomenclatures) + q_ = DB.session.execute( + select(TFunctions, TNomenclatures) .join( TNomenclatures, TNomenclatures.id_nomenclature == TFunctions.id_function, ) - .filter(TFunctions.id_zh == self.id_zh) - .filter(TNomenclatures.id_nomenclature.in_(nomenc_ids)) - .all() - ) + .where(TFunctions.id_zh == self.id_zh) + .where(TNomenclatures.id_nomenclature.in_(nomenc_ids)) + ).all() return q_ except ZHApiError as e: raise ZHApiError( @@ -445,9 +445,9 @@ def __get_id_type(self, mnemo): try: # get id_type in TNomenclatures return getattr( - DB.session.query(BibNomenclaturesTypes) - .filter(BibNomenclaturesTypes.mnemonique == mnemo) - .one(), + DB.session.execute( + select(BibNomenclaturesTypes).where(BibNomenclaturesTypes.mnemonique == mnemo) + ).scalar_one(), "id_type", ) except Exception as e: @@ -493,11 +493,12 @@ def __get_combination(self): "mnemo": nomenc.TNomenclatures.mnemonique, "id": nomenc.TNomenclatures.id_nomenclature, } - for nomenc in DB.session.query(BibNomenclaturesTypes, TNomenclatures) - .join(BibNomenclaturesTypes) - .filter(BibNomenclaturesTypes.mnemonique == "FONCTIONS_QUALIF") - .order_by(TNomenclatures.id_nomenclature) - .all() + for nomenc in DB.session.execute( + select(BibNomenclaturesTypes, TNomenclatures) + .join(BibNomenclaturesTypes) + .where(BibNomenclaturesTypes.mnemonique == "FONCTIONS_QUALIF") + .order_by(TNomenclatures.id_nomenclature) + ).all() ] # get qualif combination of selected functions @@ -510,7 +511,9 @@ def __get_qualif_cat4_cat5(self): combination = self.__get_combination() # set qualif_id qualif_id = getattr( - DB.session.query(TCorQualif).filter(TCorQualif.combination == combination).first(), + DB.session.scalars( + select(TCorQualif).where(TCorQualif.combination == combination) + ).first(), "id_qualification", ) return qualif_id @@ -531,7 +534,9 @@ def __get_qualif_cat4_cat5(self): def __get_tzh_val(self, field): try: - return getattr(DB.session.query(TZH).filter(TZH.id_zh == self.id_zh).one(), field) + return getattr( + DB.session.execute(select(TZH).where(TZH.id_zh == self.id_zh)).scalar_one(), field + ) except Exception as e: exc_type, value, tb = sys.exc_info() raise ZHApiError( @@ -584,54 +589,57 @@ def __get_qualif(self): def __get_qualif_management(self): try: cd_id_nature_naturaliste = getattr( - DB.session.query(BibNomenclaturesTypes, TNomenclatures) - .join( - TNomenclatures, - TNomenclatures.id_type == BibNomenclaturesTypes.id_type, - ) - .filter( - and_( - BibNomenclaturesTypes.mnemonique == "PLAN_GESTION", - TNomenclatures.cd_nomenclature == "5", + DB.session.execute( + select(BibNomenclaturesTypes, TNomenclatures) + .join( + TNomenclatures, + TNomenclatures.id_type == BibNomenclaturesTypes.id_type, + ) + .where( + and_( + BibNomenclaturesTypes.mnemonique == "PLAN_GESTION", + TNomenclatures.cd_nomenclature == "5", + ) ) ) - .one() + .scalar_one() .TNomenclatures, "id_nomenclature", ) selected_id_nature = [ getattr(q_.TManagementPlans, "id_nature") - for q_ in DB.session.query(TManagementPlans, TManagementStructures) - .join( - TManagementStructures, - TManagementPlans.id_structure == TManagementStructures.id_structure, - ) - .filter(TManagementStructures.id_zh == self.id_zh) - .all() + for q_ in DB.session.execute( + select(TManagementPlans, TManagementStructures) + .join( + TManagementStructures, + TManagementPlans.id_structure == TManagementStructures.id_structure, + ) + .where(TManagementStructures.id_zh == self.id_zh) + ).all() ] if cd_id_nature_naturaliste in selected_id_nature: # if id_nature == 'naturaliste' in selected plans : return return getattr( - DB.session.query(TNomenclatures) - .filter( - and_( - TNomenclatures.id_type == self.__get_id_type("HIERARCHY"), - TNomenclatures.cd_nomenclature == "OUI", + DB.session.execute( + select(TNomenclatures).where( + and_( + TNomenclatures.id_type == self.__get_id_type("HIERARCHY"), + TNomenclatures.cd_nomenclature == "OUI", + ) ) - ) - .one(), + ).scalar_one(), "id_nomenclature", ) else: return getattr( - DB.session.query(TNomenclatures) - .filter( - and_( - TNomenclatures.id_type == self.__get_id_type("HIERARCHY"), - TNomenclatures.cd_nomenclature == "NON", + DB.session.execute( + select(TNomenclatures).where( + and_( + TNomenclatures.id_type == self.__get_id_type("HIERARCHY"), + TNomenclatures.cd_nomenclature == "NON", + ) ) - ) - .one(), + ).scalar_one(), "id_nomenclature", ) except ZHApiError as e: @@ -654,16 +662,17 @@ def __get_knowledge(self): if self.active: if self.abb == "hab": is_carto = ( - DB.session.query(TZH).filter(TZH.id_zh == self.id_zh).one().is_carto_hab + DB.session.execute(select(TZH).where(TZH.id_zh == self.id_zh)) + .scalar_one() + .is_carto_hab ) if is_carto: return 3 return 2 elif self.abb in ["flore", "vertebrates", "invertebrates"]: is_other_inventory = ( - DB.session.query(TZH) - .filter(TZH.id_zh == self.id_zh) - .one() + DB.session.execute(select(TZH).where(TZH.id_zh == self.id_zh)) + .scalar_one() .is_other_inventory ) is_id_nature_plan_2 = self.__get_id_plan() @@ -676,22 +685,27 @@ def __get_knowledge(self): try: # return id_knowledge if abb function selected knowledge_id = ( - DB.session.query(TFunctions.id_knowledge) - .filter( - and_( - TFunctions.id_zh == self.id_zh, - TFunctions.id_qualification == self.qualif_id, + DB.session.execute( + select(TFunctions.id_knowledge) + .where( + and_( + TFunctions.id_zh == self.id_zh, + TFunctions.id_qualification == self.qualif_id, + ) ) + .where(TFunctions.id_function == CorRuleNomenc.nomenc_id) + .where(CorRuleNomenc.rule_id == self.rule_id) ) - .filter(TFunctions.id_function == CorRuleNomenc.nomenc_id) - .filter(CorRuleNomenc.rule_id == self.rule_id) - .one() + .scalar_one() .id_knowledge ) return ( - DB.session.query(BibNoteTypes) - .filter(BibNoteTypes.id_knowledge == knowledge_id) - .one() + DB.session.execute( + select(BibNoteTypes).where( + BibNoteTypes.id_knowledge == knowledge_id + ) + ) + .scalar_one() .note_id ) except: @@ -755,8 +769,8 @@ def __set_protection_knowledge(self): DB.session.close() def __get_id_plan(self): - q_plans = ( - DB.session.query(TManagementStructures, TManagementPlans) + q_plans = DB.session.execute( + select(TManagementStructures, TManagementPlans) .join( TManagementPlans, TManagementStructures.id_structure == TManagementPlans.id_structure, @@ -765,14 +779,13 @@ def __get_id_plan(self): TNomenclatures, TNomenclatures.id_nomenclature == TManagementPlans.id_nature, ) - .filter( + .where( and_( TManagementStructures.id_zh == self.id_zh, TNomenclatures.mnemonique == "Naturaliste", ) ) - .all() - ) + ).all() if q_plans: return True return False @@ -782,17 +795,20 @@ def __check_qualif(self, qualif_id): if self.active: attribute_id_list = [ getattr(item, "attribute_id") - for item in DB.session.query(TItems) - .filter(TItems.cor_rule_id == self.cor_rule_id) - .all() + for item in DB.session.scalars( + select(TItems).where(TItems.cor_rule_id == self.cor_rule_id) + ).all() ] if qualif_id not in attribute_id_list: raise ZHApiError( message="wrong_qualif", details="zh qualif ({}) provided for {} rule is not part of the qualif list defined in the river basin hierarchy rules".format( - DB.session.query(TNomenclatures) - .filter(TNomenclatures.id_nomenclature == qualif_id) - .one() + DB.session.execute( + select(TNomenclatures).where( + TNomenclatures.id_nomenclature == qualif_id + ) + ) + .scalar_one() .mnemonique, self.abb, ), @@ -817,17 +833,15 @@ def __check_qualif(self, qualif_id): def __set_note(self): try: if self.active: - result = ( - DB.session.query(TItems) - .filter( + result = DB.session.execute( + select(TItems).where( and_( TItems.attribute_id == self.qualif_id, TItems.cor_rule_id == self.cor_rule_id, TItems.note_type_id == self.knowledge, ) ) - .one() - ) + ).scalar_one() note = round(result.note, 2) attribute_id = result.attribute_id note_type_id = result.note_type_id @@ -858,9 +872,9 @@ def __get_denominator(self): if self.active: return max( getattr(val, "note") - for val in DB.session.query(TItems) - .filter(TItems.cor_rule_id == self.cor_rule_id) - .all() + for val in DB.session.scalars( + select(TItems).where(TItems.cor_rule_id == self.cor_rule_id) + ).all() ) except Exception as e: exc_type, value, tb = sys.exc_info() @@ -872,19 +886,23 @@ def __get_denominator(self): def __get_rule_name(self): try: return ( - DB.session.query(TRules, BibHierSubcategories) - .join(TRules) - .filter(TRules.rule_id == self.rule_id) - .one() + DB.session.execute( + select(TRules, BibHierSubcategories) + .join(TRules) + .where(TRules.rule_id == self.rule_id) + ) + .scalar_one() .BibHierSubcategories.label.capitalize() ) except NoResultFound: pass return ( - DB.session.query(TRules, BibHierCategories) - .join(TRules) - .filter(TRules.rule_id == self.rule_id) - .one() + DB.session.execute( + select(TRules, BibHierCategories) + .join(TRules) + .where(TRules.rule_id == self.rule_id) + ) + .scalar_one() .BibHierCategories.label.capitalize() ) @@ -895,13 +913,15 @@ def __get_knowledge_mnemo(self): return None else: return getattr( - DB.session.query(TNomenclatures, BibNoteTypes) - .join( - BibNoteTypes, - TNomenclatures.id_nomenclature == BibNoteTypes.id_knowledge, + DB.session.execute( + select(TNomenclatures, BibNoteTypes) + .join( + BibNoteTypes, + TNomenclatures.id_nomenclature == BibNoteTypes.id_knowledge, + ) + .where(BibNoteTypes.note_id == self.knowledge) ) - .filter(BibNoteTypes.note_id == self.knowledge) - .one() + .scalar_one() .TNomenclatures, "mnemonique", ) @@ -916,9 +936,11 @@ def __get_qualif_mnemo(self): try: if self.active: return getattr( - DB.session.query(TNomenclatures) - .filter(TNomenclatures.id_nomenclature == self.qualif_id) - .one(), + DB.session.execute( + select(TNomenclatures).where( + TNomenclatures.id_nomenclature == self.qualif_id + ) + ).scalar_one(), "label_default", ) except Exception as e: @@ -961,9 +983,9 @@ def denominator(self, value): def __get_name(self): return getattr( - DB.session.query(BibHierCategories) - .filter(BibHierCategories.abbreviation == self.abb) - .one(), + DB.session.execute( + select(BibHierCategories).where(BibHierCategories.abbreviation == self.abb) + ).scalar_one(), "label", ) @@ -1188,16 +1210,18 @@ def __get_rb(self): if len(q_rb) > 1: return get_main_rb(q_rb) return ( - DB.session.query(CorZhRb, TRiverBasin) - .join(TRiverBasin) - .filter(CorZhRb.id_zh == self.id_zh) - .one() + DB.session.execute( + select(CorZhRb, TRiverBasin).join(TRiverBasin).where(CorZhRb.id_zh == self.id_zh) + ) + .scalar_one() .TRiverBasin.id_rb ) def __check_if_rules(self): try: - if not DB.session.query(CorRbRules).filter(CorRbRules.rb_id == self.rb_id).first(): + if not DB.session.scalars( + select(CorRbRules).where(CorRbRules.rb_id == self.rb_id) + ).first(): raise ZHApiError( message="no_rb_rules", details="no existing rules for the river basin", @@ -1215,9 +1239,15 @@ def __check_if_rules(self): @staticmethod def get_denom(rb_id, col_name): - rb_name = DB.session.query(TRiverBasin).filter(TRiverBasin.id_rb == rb_id).one().name + rb_name = ( + DB.session.execute(select(TRiverBasin).where(TRiverBasin.id_rb == rb_id)) + .scalar_one() + .name + ) return getattr( - DB.session.query(RbNotesSummary).filter(RbNotesSummary.bassin_versant == rb_name).one(), + DB.session.execute( + select(RbNotesSummary).where(RbNotesSummary.bassin_versant == rb_name) + ).scalar_one(), col_name, ) @@ -1236,9 +1266,10 @@ def get_str_note(note, denominator): def as_dict(self): return { - "river_basin_name": DB.session.query(TRiverBasin) - .filter(TRiverBasin.id_rb == self.rb_id) - .one() + "river_basin_name": DB.session.execute( + select(TRiverBasin).where(TRiverBasin.id_rb == self.rb_id) + ) + .scalar_one() .name, "volet1": self.volet1.__str__(), "volet2": self.volet2.__str__(), diff --git a/backend/gn_module_zh/model/cards.py b/backend/gn_module_zh/model/cards.py index 90ffc3ce..7f63bc02 100644 --- a/backend/gn_module_zh/model/cards.py +++ b/backend/gn_module_zh/model/cards.py @@ -3,6 +3,7 @@ from ref_geo.models import BibAreasTypes, LAreas from geonature.utils.env import DB +from sqlalchemy.sql import select from pypn_habref_api.models import Habref from pypnnomenclature.models import TNomenclatures @@ -32,15 +33,17 @@ def get_mnemo(ids): if ids: if type(ids) is int: return ( - DB.session.query(TNomenclatures) - .filter(TNomenclatures.id_nomenclature == ids) - .one() + DB.session.execute( + select(TNomenclatures).where(TNomenclatures.id_nomenclature == ids) + ) + .scalar_one() .label_default ) return [ - DB.session.query(TNomenclatures) - .filter(TNomenclatures.id_nomenclature == id) - .one() + DB.session.execute( + select(TNomenclatures).where(TNomenclatures.id_nomenclature == id) + ) + .scalar_one() .label_default for id in ids ] @@ -50,18 +53,16 @@ def get_mnemo(ids): def get_cd_and_mnemo(ids): if ids: if type(ids) is int: - result = ( - DB.session.query(TNomenclatures) - .filter(TNomenclatures.id_nomenclature == ids) - .one() - ) + result = DB.session.execute( + select(TNomenclatures).where(TNomenclatures.id_nomenclature == ids) + ).scalar_one() return (result.cd_nomenclature, result.label_default) - return ( - DB.session.query(TNomenclatures.cd_nomenclature, TNomenclatures.label_default) - .filter(TNomenclatures.id_nomenclature.in_(ids)) - .all() - ) + return DB.session.execute( + select(TNomenclatures.cd_nomenclature, TNomenclatures.label_default).where( + TNomenclatures.id_nomenclature.in_(ids) + ) + ).all() return [] @@ -380,21 +381,19 @@ def __init__(self, id_corine_bio, id_cahier_hab, id_preservation_state, hab_cove self.hab_cover: int = hab_cover def __str__(self): - hab_biotope = ( - DB.session.query(Habref) - .filter(Habref.lb_code == self.id_corine_bio) - .filter(Habref.cd_typo == 22) - .one() - ) + hab_biotope = DB.session.execute( + select(Habref).where(Habref.lb_code == self.id_corine_bio).where(Habref.cd_typo == 22) + ).scalar_one() biotope_lb_hab_fr = hab_biotope.lb_hab_fr biotope_lb_code = hab_biotope.lb_code - cahier = DB.session.query(Habref).filter(Habref.cd_hab == self.id_cahier_hab).one() + cahier = DB.session.execute( + select(Habref).where(Habref.cd_hab == self.id_cahier_hab) + ).scalar_one() cahier_lb_hab_fr = cahier.lb_hab_fr cahier_lb_code = cahier.lb_code priority = ( - DB.session.query(CorChStatus) - .filter(CorChStatus.lb_code == cahier_lb_code) - .one() + DB.session.execute(select(CorChStatus).where(CorChStatus.lb_code == cahier_lb_code)) + .scalar_one() .priority ) return { @@ -505,19 +504,22 @@ def __str__(self): def __get_river_basins(self): return [ name - for (name,) in DB.session.query(TRiverBasin.name) - .filter(TRiverBasin.id_rb == CorZhRb.id_rb) - .filter(CorZhRb.id_zh == self.id_zh) - .all() + for (name,) in DB.session.execute( + select(TRiverBasin.name) + .where(TRiverBasin.id_rb == CorZhRb.id_rb) + .where(CorZhRb.id_zh == self.id_zh) + ).all() ] def __get_hydro_zones(self): return [ name - for (name,) in DB.session.query(THydroArea.name) - .filter(THydroArea.id_hydro == CorZhHydro.id_hydro) - .filter(CorZhHydro.id_zh == self.id_zh) - .distinct() + for (name,) in DB.session.execute( + select(THydroArea.name) + .where(THydroArea.id_hydro == CorZhHydro.id_hydro) + .where(CorZhHydro.id_zh == self.id_zh) + .distinct() + ).all() ] @@ -677,9 +679,10 @@ def other_ref_geo(self, ref_geo): for ref in CorZhArea.get_ref_geo_info(self.id_zh, id_types): for i in ref: type_code = ( - DB.session.query(BibAreasTypes) - .filter(BibAreasTypes.id_type == i.LAreas.id_type) - .one() + DB.session.execute( + select(BibAreasTypes).where(BibAreasTypes.id_type == i.LAreas.id_type) + ) + .scalar_one() .type_code ) refs.append( @@ -722,11 +725,11 @@ def protections(self, protections): self.__protections: list(int) = protections def __str_protections(self): - q_protections = ( - DB.session.query(CorProtectionLevelType) - .filter(CorProtectionLevelType.id_protection_status.in_(self.protections)) - .all() - ) + q_protections = DB.session.scalars( + select(CorProtectionLevelType).where( + CorProtectionLevelType.id_protection_status.in_(self.protections) + ) + ).all() temp = [ { "status": Utils.get_mnemo(protection.id_protection_status), @@ -777,9 +780,10 @@ def set_management(self, id_org, plans): def __str__(self): return { - "structure": DB.session.query(BibOrganismes) - .filter(BibOrganismes.id_org == self.id_org) - .one() + "structure": DB.session.execute( + select(BibOrganismes).where(BibOrganismes.id_org == self.id_org) + ) + .scalar_one() .name, "plans": [plan.__str__() for plan in self.plans], } @@ -819,16 +823,16 @@ def __init__(self, id_area, id_doc_type, id_cors, remark): def __str__(self): return { - "commune": DB.session.query(LAreas) - .filter(LAreas.id_area == self.id_area) - .one() + "commune": DB.session.execute(select(LAreas).where(LAreas.id_area == self.id_area)) + .scalar_one() .area_name, "type_doc": Utils.get_mnemo(self.id_doc_type), "type_classement": [ Utils.get_mnemo( - DB.session.query(CorUrbanTypeRange) - .filter(CorUrbanTypeRange.id_cor == id) - .one() + DB.session.execute( + select(CorUrbanTypeRange).where(CorUrbanTypeRange.id_cor == id) + ) + .scalar_one() .id_range_type ) for id in self.id_cors @@ -1009,9 +1013,10 @@ def __init__(self, id_action, id_priority_level, remark): def __str__(self): return { - "proposition": DB.session.query(BibActions) - .filter(BibActions.id_action == self.id_action) - .one() + "proposition": DB.session.execute( + select(BibActions).where(BibActions.id_action == self.id_action) + ) + .scalar_one() .name, "niveau": Utils.get_mnemo(self.id_priority_level), "remarque": Utils.get_string(self.remark), diff --git a/backend/gn_module_zh/model/code.py b/backend/gn_module_zh/model/code.py index 132fcd57..3189f1d1 100644 --- a/backend/gn_module_zh/model/code.py +++ b/backend/gn_module_zh/model/code.py @@ -1,7 +1,7 @@ import sys from geonature.utils.env import DB -from sqlalchemy.sql import func +from sqlalchemy.sql import func, select from ..api_error import ZHApiError from .zh import ZH @@ -18,15 +18,20 @@ def get_departments(self): try: departments = CorZhArea.get_departments(self.id_zh) area = 0 - my_geom = ( - DB.session.query(func.ST_Transform(func.ST_SetSRID(TZH.geom, 4326), 2154)) - .filter(TZH.id_zh == self.id_zh) - .one()[0] - ) + my_geom = DB.session.execute( + select(func.ST_Transform(func.ST_SetSRID(TZH.geom, 4326), 2154)).where( + TZH.id_zh == self.id_zh + ) + ).scalar_one() main_dep = None for dep in departments: - if DB.session.scalar(dep.LAreas.geom.ST_Intersection(my_geom).ST_Area()) > area: - area = DB.session.scalar(dep.LAreas.geom.ST_Intersection(my_geom).ST_Area()) + if ( + DB.session.scalar(select(dep.LAreas.geom.ST_Intersection(my_geom).ST_Area())) + > area + ): + area = DB.session.scalar( + select(dep.LAreas.geom.ST_Intersection(my_geom).ST_Area()) + ) main_dep = dep.LAreas.area_code if main_dep is None: raise ZHApiError(message="no_department", details="main_dep value is none") @@ -44,7 +49,7 @@ def get_organism(self): def get_number(self): base_code = self.get_departments() + self.get_organism() - q_codes = DB.session.query(TZH).filter(TZH.code.contains(base_code)).all() + q_codes = DB.session.scalars(select(TZH).where(TZH.code.contains(base_code))).all() if q_codes: code_numbers = [int(zh.code.split(self.get_organism())[1]) for zh in q_codes] max_code = max(code_numbers) diff --git a/backend/gn_module_zh/model/repositories.py b/backend/gn_module_zh/model/repositories.py index f2100867..20b3a679 100644 --- a/backend/gn_module_zh/model/repositories.py +++ b/backend/gn_module_zh/model/repositories.py @@ -1,5 +1,6 @@ from geonature.utils.env import DB from werkzeug.exceptions import NotFound +from sqlalchemy.sql import select class ZhRepository: @@ -17,7 +18,7 @@ def delete(self, id_zh, user, user_cruved): - id_zh: integer - info_user: TRole object model""" level = user_cruved["D"] - zh = DB.session.query(self.model).get(id_zh) + zh = DB.session.get(self.model, id_zh) if zh: zh = zh.get_zh_if_allowed(user, "D", level) DB.session.delete(zh) diff --git a/backend/gn_module_zh/model/zh.py b/backend/gn_module_zh/model/zh.py index 404759a3..050801e9 100644 --- a/backend/gn_module_zh/model/zh.py +++ b/backend/gn_module_zh/model/zh.py @@ -1,5 +1,6 @@ # instance de la BDD from geonature.utils.env import DB +from sqlalchemy.sql import select from .zh_schema import ( TZH, @@ -32,11 +33,11 @@ class ZH(TZH): __abstract__ = True def __init__(self, id_zh): - self.zh = DB.session.query(TZH).filter(TZH.id_zh == id_zh).one() + self.zh = DB.session.get(TZH, id_zh) @staticmethod def get_data_by_id(table_name, id_zh): - return DB.session.query(table_name).filter(table_name.id_zh == id_zh).all() + return DB.session.scalars(select(table_name).where(table_name.id_zh == id_zh)).all() def get_id_lims(self): lim_list = CorLimList.get_lims_by_id(self.zh.id_lim_list) @@ -141,11 +142,11 @@ def get_managements(self): q_management_structures = ZH.get_data_by_id(TManagementStructures, self.zh.id_zh) managements = [] for management in q_management_structures: - q_management_plans = ( - DB.session.query(TManagementPlans) - .filter(TManagementPlans.id_structure == management.id_structure) - .all() - ) + q_management_plans = DB.session.scalars( + select(TManagementPlans).where( + TManagementPlans.id_structure == management.id_structure + ) + ).all() plans = [] if q_management_plans: for plan in q_management_plans: @@ -178,9 +179,12 @@ def get_instruments(self): def get_protections(self): return { "protections": [ - DB.session.query(CorProtectionLevelType) - .filter(CorProtectionLevelType.id_protection == protec) - .one() + DB.session.execute( + select(CorProtectionLevelType).where( + CorProtectionLevelType.id_protection == protec + ) + ) + .scalar_one() .id_protection_status for protec in [ protection.id_protection @@ -197,9 +201,9 @@ def get_urban_docs(self): "id_doc_type": urban_doc.id_doc_type, "id_cors": [ doc.id_cor - for doc in DB.session.query(CorZhDocRange) - .filter(CorZhDocRange.id_doc == urban_doc.id_doc) - .all() + for doc in DB.session.scalars( + select(CorZhDocRange).where(CorZhDocRange.id_doc == urban_doc.id_doc) + ).all() ], "remark": urban_doc.remark, } @@ -252,9 +256,9 @@ def get_regions(self, query): for municipality in query: if municipality.LiMunicipalities.insee_reg not in region_list: region_list.append(municipality.LiMunicipalities.insee_reg) - q_region = ( - DB.session.query(InseeRegions).filter(InseeRegions.insee_reg.in_(region_list)).all() - ) + q_region = DB.session.scalars( + select(InseeRegions).where(InseeRegions.insee_reg.in_(region_list)) + ).all() regions = [region.region_name for region in q_region] return regions diff --git a/backend/gn_module_zh/model/zh_schema.py b/backend/gn_module_zh/model/zh_schema.py index e8e2ba19..7a678cd5 100644 --- a/backend/gn_module_zh/model/zh_schema.py +++ b/backend/gn_module_zh/model/zh_schema.py @@ -91,12 +91,13 @@ class Nomenclatures(TNomenclatures): @staticmethod def get_nomenclature_info(bib_mnemo): - q = TNomenclatures.query.filter_by( - id_type=select([func.ref_nomenclatures.get_id_nomenclature_type(bib_mnemo)]) + # todo + q = select(TNomenclatures).where( + TNomenclatures.id_type == (func.ref_nomenclatures.get_id_nomenclature_type(bib_mnemo)) ) if bib_mnemo == "SDAGE": q = q.order_by(TNomenclatures.id_nomenclature) - return q.all() + return DB.session.scalars(q).all() @serializable @@ -127,7 +128,8 @@ class BibSiteSpace(DB.Model): @staticmethod def get_bib_site_spaces(): - bib_site_spaces = DB.session.query(BibSiteSpace).all() + # bib_site_spaces = DB.session.execute(select(BibSiteSpace)).scalars().all() + bib_site_spaces = DB.session.scalars(select(BibSiteSpace)).all() bib_site_spaces_list = [bib_site_space.as_dict() for bib_site_space in bib_site_spaces] return bib_site_spaces_list @@ -143,12 +145,15 @@ class BibOrganismes(DB.Model): @staticmethod def get_abbrevation(id_org): - org = DB.session.query(BibOrganismes).filter(BibOrganismes.id_org == id_org).one() + org = DB.session.execute( + select(BibOrganismes).where(BibOrganismes.id_org == id_org) + ).scalar_one() return org.abbrevation @staticmethod def get_bib_organisms(org_type): - bib_organismes = DB.session.query(BibOrganismes).all() + # bib_organismes = DB.session.execute(select(BibOrganismes)).scalars().all() + bib_organismes = DB.session.scalars(select(BibOrganismes)).all() if org_type == "operator": return [bib_org.as_dict() for bib_org in bib_organismes if bib_org.is_op_org] elif org_type == "management_structure": @@ -165,7 +170,7 @@ class CorLimList(DB.Model): id_lim = DB.Column(DB.Integer, ForeignKey(TNomenclatures.id_nomenclature), primary_key=True) def get_lims_by_id(id): - return DB.session.query(CorLimList).filter(CorLimList.id_lim_list == id).all() + return DB.session.scalars(select(CorLimList).where(CorLimList.id_lim_list == id)).all() @serializable @@ -262,53 +267,56 @@ def get_geofeature(self, recursif=True, relationships=()): @staticmethod def get_site_space_name(id): - return DB.session.query(BibSiteSpace).filter(BibSiteSpace.id_site_space == id).one().name + return ( + DB.session.execute(select(BibSiteSpace).where(BibSiteSpace.id_site_space == id)) + .scalar_one() + .name + ) @staticmethod def get_tzh_by_id(id): - return DB.session.query(TZH).filter(TZH.id_zh == id).one() + return DB.session.execute(select(TZH).where(TZH.id_zh == id)).scalar_one() @staticmethod def get_zh_area_intersected(zh_area_type, id_zh_geom): if zh_area_type == "river_basin": - q = ( - DB.session.query(TRiverBasin) - .filter(TRiverBasin.geom.ST_Intersects(cast(id_zh_geom, Geography))) - .all() - ) + q = DB.session.execute( + select(TRiverBasin).where( + TRiverBasin.geom.ST_Intersects(cast(id_zh_geom, Geography)) + ) + ).all() if zh_area_type == "hydro_area": - q = ( - DB.session.query(THydroArea) - .filter(THydroArea.geom.ST_Intersects(cast(id_zh_geom, Geography))) - .all() - ) + q = DB.session.execute( + select(THydroArea).where( + THydroArea.geom.ST_Intersects(cast(id_zh_geom, Geography)) + ) + ).all() if zh_area_type == "fct_area": - q = ( - DB.session.query(TFctArea) - .filter(TFctArea.geom.ST_Intersects(cast(id_zh_geom, Geography))) - .all() - ) + q = DB.session.execute( + select(TFctArea).where(TFctArea.geom.ST_Intersects(cast(id_zh_geom, Geography))) + ).all() return q @hybrid_property def delims(self): - delims = [ - element.TNomenclatures.mnemonique - for element in DB.session.query(CorLimList, TNomenclatures) - .filter(CorLimList.id_lim_list == self.id_lim_list) - .filter(TNomenclatures.id_nomenclature == CorLimList.id_lim) - .all() - ] + query = select(CorLimList, TNomenclatures).where( + and_( + TNomenclatures.id_nomenclature == CorLimList.id_lim, + CorLimList.id_lim_list == self.id_lim_list, + ) + ) + delims = [element.TNomenclatures.mnemonique for element in DB.session.execute(query).all()] return ", ".join([str(item) for item in delims]) @hybrid_property def bassin_versant(self): bassin_versant = [ name - for (name,) in DB.session.query(TRiverBasin.name) - .filter(TRiverBasin.id_rb == CorZhRb.id_rb) - .filter(CorZhRb.id_zh == self.id_zh) - .all() + for (name,) in DB.session.execute( + select(TRiverBasin.name) + .where(TRiverBasin.id_rb == CorZhRb.id_rb) + .where(CorZhRb.id_zh == self.id_zh) + ).all() ] return ", ".join([str(item) for item in bassin_versant]) @@ -324,31 +332,32 @@ class CorZhArea(DB.Model): @staticmethod def get_id_type(mnemo): return ( - DB.session.query(BibAreasTypes).filter(BibAreasTypes.type_name == mnemo).one().id_type + DB.session.scalars(select(BibAreasTypes).where(BibAreasTypes.type_name == mnemo)) + .one() + .id_type ) @staticmethod def get_departments(id_zh): - return ( - DB.session.query(CorZhArea, LAreas, TZH) + query = ( + select(CorZhArea, LAreas, TZH) .join(LAreas) - .filter( + .where( CorZhArea.id_zh == id_zh, LAreas.id_type == CorZhArea.get_id_type("Départements"), TZH.id_zh == id_zh, ) - .all() ) + return DB.session.execute(query).all() @staticmethod def get_municipalities_info(id_zh): - return ( - DB.session.query(CorZhArea, LiMunicipalities, TZH) + return DB.session.execute( + select(CorZhArea, LiMunicipalities, TZH) .join(LiMunicipalities, LiMunicipalities.id_area == CorZhArea.id_area) - .filter(CorZhArea.id_zh == id_zh, TZH.id_zh == id_zh) + .where(CorZhArea.id_zh == id_zh, TZH.id_zh == id_zh) .order_by(LiMunicipalities.nom_com) - .all() - ) + ).all() @staticmethod def get_id_types_ref_geo(id_zh, ref_geo_config): @@ -356,9 +365,12 @@ def get_id_types_ref_geo(id_zh, ref_geo_config): for ref in ref_geo_config: if ref["active"]: ids.append( - DB.session.query(BibAreasTypes) - .filter(BibAreasTypes.type_code == ref["type_code_ref_geo"]) - .one() + DB.session.execute( + select(BibAreasTypes).where( + BibAreasTypes.type_code == ref["type_code_ref_geo"] + ) + ) + .scalar_one() .id_type ) return ids @@ -366,10 +378,11 @@ def get_id_types_ref_geo(id_zh, ref_geo_config): @staticmethod def get_ref_geo_info(id_zh, id_types): return [ - DB.session.query(CorZhArea, LAreas, TZH) - .join(LAreas) - .filter(CorZhArea.id_zh == id_zh, LAreas.id_type == id_type, TZH.id_zh == id_zh) - .all() + DB.session.scalars( + select(CorZhArea, LAreas, TZH) + .join(LAreas) + .where(CorZhArea.id_zh == id_zh, LAreas.id_type == id_type, TZH.id_zh == id_zh) + ).all() for id_type in id_types ] @@ -441,13 +454,12 @@ class CorZhRef(DB.Model): @staticmethod def get_references_by_id(id_zh): - return ( - DB.session.query(TReferences) + return DB.session.scalars( + select(TReferences) .join(CorZhRef) - .filter(CorZhRef.id_zh == id_zh) + .where(CorZhRef.id_zh == id_zh) .order_by(TReferences.pub_year.desc()) - .all() - ) + ).all() class CorZhLimFs(DB.Model): @@ -465,17 +477,16 @@ class CorSdageSage(DB.Model): @staticmethod def get_id_sdage_list(): - q_id_sdages = DB.session.query(func.distinct(CorSdageSage.id_sdage)).all() + q_id_sdages = DB.session.execute(select(func.distinct(CorSdageSage.id_sdage))).all() return [id[0] for id in q_id_sdages] @staticmethod def get_sage_by_id(id): - return ( - DB.session.query(CorSdageSage, TNomenclatures) + return DB.session.execute( + select(CorSdageSage, TNomenclatures) .join(TNomenclatures, TNomenclatures.id_nomenclature == CorSdageSage.id_sage) - .filter(CorSdageSage.id_sdage == id) - .all() - ) + .where(CorSdageSage.id_sdage == id) + ).all() class BibCb(DB.Model): @@ -487,17 +498,19 @@ class BibCb(DB.Model): @staticmethod def get_label(): - return ( - DB.session.query(BibCb, Habref) + return DB.session.execute( + select(BibCb, Habref) .join(Habref, BibCb.lb_code == Habref.lb_code) - .filter(Habref.cd_typo == 22) + .where(Habref.cd_typo == 22) .order_by(BibCb.lb_code) - .all() - ) + ).all() @staticmethod def get_ch(lb_code): # get cd_hab_sortie from lb_code of selected Corine Biotope + # !!! est-ce que method utilisée qqpart ? + # todo + """ cd_hab_sortie = ( DB.session.query(Habref) .filter(and_(Habref.lb_code == lb_code, Habref.cd_typo == 22)) @@ -505,11 +518,13 @@ def get_ch(lb_code): .cd_hab ) # get all cd_hab_entre corresponding to cd_hab_sortie + #todo q_cd_hab_entre = ( DB.session.query(CorespHab).filter(CorespHab.cd_hab_sortie == cd_hab_sortie).all() ) # get list of cd_hab_entre/lb_code/lb_hab_fr for each cahier habitat ch = [] + #todo for q in q_cd_hab_entre: ch.append( { @@ -525,6 +540,7 @@ def get_ch(lb_code): } ) return ch + """ class CorChStatus(DB.Model): @@ -544,15 +560,14 @@ class CorImpactTypes(DB.Model): @staticmethod def get_impacts(): - return ( - DB.session.query(CorImpactTypes, TNomenclatures) + return DB.session.execute( + select(CorImpactTypes, TNomenclatures) .join( TNomenclatures, TNomenclatures.id_nomenclature == CorImpactTypes.id_impact, ) - .filter(CorImpactTypes.active) - .all() - ) + .where(CorImpactTypes.active) + ).all() # and_(CorImpactTypes.id_impact_type == id_type, CorImpactTypes.active)).all() # def get_impact_type_list(): @@ -586,45 +601,44 @@ class CorMainFct(DB.Model): @staticmethod def get_functions(nomenc_ids): - return ( - DB.session.query(CorMainFct, TNomenclatures) + return DB.session.execute( + select(CorMainFct, TNomenclatures) .join(TNomenclatures, TNomenclatures.id_nomenclature == CorMainFct.id_function) - .filter(CorMainFct.active) - .filter(CorMainFct.id_function.in_(nomenc_ids)) - .all() - ) + .where(CorMainFct.active) + .where(CorMainFct.id_function.in_(nomenc_ids)) + ).all() @staticmethod def get_all_functions(nomenc_ids): - return ( - DB.session.query(CorMainFct, TNomenclatures) + query = ( + select(CorMainFct, TNomenclatures) .join(TNomenclatures, TNomenclatures.id_nomenclature == CorMainFct.id_function) - .filter(CorMainFct.id_function.in_(nomenc_ids)) - .all() + .where(CorMainFct.id_function.in_(nomenc_ids)) ) + return DB.session.execute(query).all() @staticmethod def get_main_function_list(ids): - q_id_types = DB.session.query(func.distinct(CorMainFct.id_main_function)).all() + # méthode utilisée ??? + q_id_types = DB.session.scalars(select(func.distinct(CorMainFct.id_main_function))).all() return [id[0] for id in q_id_types if id[0] in ids] @staticmethod def get_function_by_main_function(id_main): - return ( - DB.session.query(CorMainFct, TNomenclatures) + # méthode utilisée ??? + return DB.session.execute( + select(CorMainFct, TNomenclatures) .join(TNomenclatures, TNomenclatures.id_nomenclature == CorMainFct.id_function) - .filter(and_(CorMainFct.id_main_function == id_main, CorMainFct.active)) - .all() - ) + .where(and_(CorMainFct.id_main_function == id_main, CorMainFct.active)) + ).all() @staticmethod def get_mnemo_type(id_type): if id_type: - return ( - DB.session.query(TNomenclatures) - .filter(TNomenclatures.id_nomenclature == id_type) - .one() - ) + # pas testé + return DB.session.execute( + select(TNomenclatures).where(TNomenclatures.id_nomenclature == id_type) + ).scalar_one() else: return "" @@ -658,8 +672,10 @@ class CorImpactList(DB.Model): @staticmethod def get_impacts_by_uuid(uuid_activity): return ( - DB.session.query(CorImpactList) - .filter(CorImpactList.id_impact_list == uuid_activity) + DB.session.execute( + select(CorImpactList).where(CorImpactList.id_impact_list == uuid_activity) + ) + .scalars() .all() ) @@ -741,13 +757,12 @@ def get_functions_by_id_and_category(id_zh, category, is_eval=False): for nomenclature in Nomenclatures.get_nomenclature_info("FONCTIONS_QUALIF") ] - return ( - DB.session.query(TFunctions) - .filter(TFunctions.id_zh == id_zh) - .filter(TFunctions.id_function.in_(function_ids)) - .filter(TFunctions.id_qualification.in_(qualif_ids)) - .all() - ) + return DB.session.scalars( + select(TFunctions) + .where(TFunctions.id_zh == id_zh) + .where(TFunctions.id_function.in_(function_ids)) + .where(TFunctions.id_qualification.in_(qualif_ids)) + ).all() class THabHeritage(DB.Model): @@ -773,20 +788,21 @@ class CorUrbanTypeRange(DB.Model): @staticmethod def get_range_by_doc(doc_id): - q_ranges = ( - DB.session.query(CorUrbanTypeRange) - .filter(CorUrbanTypeRange.id_doc_type == doc_id) - .all() - ) + q_ranges = DB.session.scalars( + select(CorUrbanTypeRange).where(CorUrbanTypeRange.id_doc_type == doc_id) + ).all() ranges = [] for range in q_ranges: ranges.append( { "id_cor": range.id_cor, "id_nomenclature": range.id_range_type, - "mnemonique": DB.session.query(TNomenclatures) - .filter(TNomenclatures.id_nomenclature == range.id_range_type) - .one() + "mnemonique": DB.session.execute( + select(TNomenclatures).where( + TNomenclatures.id_nomenclature == range.id_range_type + ) + ) + .scalar_one() .mnemonique, } ) @@ -834,7 +850,7 @@ class BibActions(DB.Model): @staticmethod def get_bib_actions(): - q_bib_actions = DB.session.query(BibActions).all() + q_bib_actions = DB.session.scalars(select(BibActions)).all() bib_actions_list = [bib_action.as_dict() for bib_action in q_bib_actions] return bib_actions_list diff --git a/backend/gn_module_zh/nomenclatures.py b/backend/gn_module_zh/nomenclatures.py index ad6f28cd..eaf3e08e 100644 --- a/backend/gn_module_zh/nomenclatures.py +++ b/backend/gn_module_zh/nomenclatures.py @@ -4,6 +4,7 @@ from pypn_habref_api.models import CorespHab, Habref, TypoRef from pypnnomenclature.models import BibNomenclaturesTypes, TNomenclatures from sqlalchemy import and_ +from sqlalchemy.sql import select from .api_error import ZHApiError from .model.zh_schema import ( @@ -61,41 +62,46 @@ def get_corine_biotope(): def get_ch(lb_code): try: - CH_typo = DB.session.query(TypoRef).filter(TypoRef.cd_table == "TYPO_CH").one().cd_typo + CH_typo = ( + DB.session.execute(select(TypoRef).where(TypoRef.cd_table == "TYPO_CH")) + .scalar_one() + .cd_typo + ) CB_typo = ( - DB.session.query(TypoRef) - .filter(TypoRef.cd_table == "TYPO_CORINE_BIOTOPES") - .one() + DB.session.execute(select(TypoRef).where(TypoRef.cd_table == "TYPO_CORINE_BIOTOPES")) + .scalar_one() .cd_typo ) # get cd_hab_sortie list from lb_code of selected Corine Biotope cd_hab_sortie = ( - DB.session.query(Habref) - .filter(and_(Habref.lb_code == lb_code, Habref.cd_typo == CB_typo)) - .one() + DB.session.execute( + select(Habref).where(and_(Habref.lb_code == lb_code, Habref.cd_typo == CB_typo)) + ) + .scalar_one() .cd_hab ) # get all cd_hab_entre corresponding to cd_hab_sortie - q_cd_hab_entre = ( - DB.session.query(CorespHab) - .filter( + q_cd_hab_entre = DB.session.scalars( + select(CorespHab).where( and_(CorespHab.cd_hab_sortie == cd_hab_sortie, CorespHab.cd_typo_entre == CH_typo) ) - .all() - ) + ).all() # get list of cd_hab_entre/lb_code/lb_hab_fr for each cahier habitat ch = [] for q in q_cd_hab_entre: - hab = DB.session.query(Habref).filter(Habref.cd_hab == q.cd_hab_entre).one() + hab = DB.session.execute( + select(Habref).where(Habref.cd_hab == q.cd_hab_entre) + ).scalar_one() ch.append( { "cd_hab": q.cd_hab_entre, "front_name": hab.lb_code + " - " + hab.lb_hab_fr, "lb_code": hab.lb_code, "lb_hab_fr": hab.lb_hab_fr, - "priority": DB.session.query(CorChStatus) - .filter(CorChStatus.lb_code == hab.lb_code) - .one() + "priority": DB.session.execute( + select(CorChStatus).where(CorChStatus.lb_code == hab.lb_code) + ) + .scalar_one() .priority, } ) @@ -138,9 +144,12 @@ def get_impact_category(impact): # get mnemonique of id_impact_type if impact.CorImpactTypes.id_impact_type is not None: return ( - DB.session.query(TNomenclatures) - .filter(TNomenclatures.id_nomenclature == impact.CorImpactTypes.id_impact_type) - .one() + DB.session.execute( + select(TNomenclatures).where( + TNomenclatures.id_nomenclature == impact.CorImpactTypes.id_impact_type + ) + ) + .scalar_one() .mnemonique ) return "Aucun" @@ -150,18 +159,19 @@ def get_function_list(mnemo): try: # get id_type of mnemo (ex : 'FONCTIONS_HYDRO') in BibNomenclatureTypes id_type_main_function = ( - DB.session.query(BibNomenclaturesTypes) - .filter(BibNomenclaturesTypes.mnemonique == mnemo) - .one() + DB.session.execute( + select(BibNomenclaturesTypes).where(BibNomenclaturesTypes.mnemonique == mnemo) + ) + .scalar_one() .id_type ) # get list of TNomenclatures ids by id_type nomenclature_ids = [ nomenc.id_nomenclature - for nomenc in DB.session.query(TNomenclatures) - .filter(TNomenclatures.id_type == id_type_main_function) - .all() + for nomenc in DB.session.scalars( + select(TNomenclatures).where(TNomenclatures.id_type == id_type_main_function) + ).all() ] return [ @@ -169,9 +179,12 @@ def get_function_list(mnemo): "id_nomenclature": function.CorMainFct.id_function, "mnemonique": function.TNomenclatures.mnemonique, "id_category": function.CorMainFct.id_main_function, - "category": DB.session.query(TNomenclatures) - .filter(TNomenclatures.id_nomenclature == function.CorMainFct.id_main_function) - .one() + "category": DB.session.execute( + select(TNomenclatures).where( + TNomenclatures.id_nomenclature == function.CorMainFct.id_main_function + ) + ) + .scalar_one() .mnemonique.upper(), } for function in CorMainFct.get_functions(nomenclature_ids) @@ -188,18 +201,19 @@ def get_all_function_list(mnemo): try: # get id_type of mnemo (ex : 'FONCTIONS_HYDRO') in BibNomenclatureTypes id_type_main_function = ( - DB.session.query(BibNomenclaturesTypes) - .filter(BibNomenclaturesTypes.mnemonique == mnemo) - .one() + DB.session.execute( + select(BibNomenclaturesTypes).where(BibNomenclaturesTypes.mnemonique == mnemo) + ) + .scalar_one() .id_type ) # get list of TNomenclatures ids by id_type nomenclature_ids = [ nomenc.id_nomenclature - for nomenc in DB.session.query(TNomenclatures) - .filter(TNomenclatures.id_type == id_type_main_function) - .all() + for nomenc in DB.session.scalars( + select(TNomenclatures).where(TNomenclatures.id_type == id_type_main_function) + ).all() ] return [ @@ -207,9 +221,12 @@ def get_all_function_list(mnemo): "id_nomenclature": function.CorMainFct.id_function, "mnemonique": function.TNomenclatures.mnemonique, "id_category": function.CorMainFct.id_main_function, - "category": DB.session.query(TNomenclatures) - .filter(TNomenclatures.id_nomenclature == function.CorMainFct.id_main_function) - .one() + "category": DB.session.execute( + select(TNomenclatures).where( + TNomenclatures.id_nomenclature == function.CorMainFct.id_main_function + ) + ) + .scalar_one() .mnemonique.upper(), } for function in CorMainFct.get_all_functions(nomenclature_ids) @@ -245,21 +262,27 @@ def get_protections(): return [ { "id_protection_status": protection.id_protection_status, - "mnemonique_status": DB.session.query(TNomenclatures) - .filter(TNomenclatures.id_nomenclature == protection.id_protection_status) - .one() + "mnemonique_status": DB.session.execute( + select(TNomenclatures).where( + TNomenclatures.id_nomenclature == protection.id_protection_status + ) + ) + .scalar_one() .mnemonique, "id_protection_level": protection.id_protection_level, - "mnemonique_level": DB.session.query(TNomenclatures) - .filter(TNomenclatures.id_nomenclature == protection.id_protection_level) - .one() + "mnemonique_level": DB.session.execute( + select(TNomenclatures).where( + TNomenclatures.id_nomenclature == protection.id_protection_level + ) + ) + .scalar_one() .mnemonique, "category": get_protection_category(protection), "category_id": protection.id_protection_type, } - for protection in DB.session.query(CorProtectionLevelType) - .order_by(CorProtectionLevelType.id_protection) - .all() + for protection in DB.session.scalars( + select(CorProtectionLevelType).order_by(CorProtectionLevelType.id_protection) + ).all() ] except Exception as e: exc_type, value, tb = sys.exc_info() @@ -272,9 +295,12 @@ def get_protections(): def get_protection_category(protection): if protection.id_protection_type is not None: return ( - DB.session.query(TNomenclatures) - .filter(TNomenclatures.id_nomenclature == protection.id_protection_type) - .one() + DB.session.execute( + select(TNomenclatures).where( + TNomenclatures.id_nomenclature == protection.id_protection_type + ) + ) + .scalar_one() .mnemonique ) return "Autre" diff --git a/backend/gn_module_zh/search.py b/backend/gn_module_zh/search.py index e7373ae6..a97dbe03 100644 --- a/backend/gn_module_zh/search.py +++ b/backend/gn_module_zh/search.py @@ -5,6 +5,7 @@ from pypnnomenclature.models import TNomenclatures from sqlalchemy import and_, desc, func, or_ from sqlalchemy.sql.expression import select +from sqlalchemy.orm import aliased from utils_flask_sqla.generic import GenericQuery from .api_error import ZHApiError @@ -40,7 +41,7 @@ def strip_accents(s): def main_search(query, json): for key in json.keys(): if key in TZH.__table__.columns: - query = query.filter(getattr(TZH, key) == json[key]) + query = query.where(getattr(TZH, key) == json[key]) sdage = json.get("sdage") if sdage is not None: query = filter_sdage(query, sdage) @@ -111,7 +112,7 @@ def main_search(query, json): def filter_sdage(query, json: dict): ids = [obj.get("id_nomenclature") for obj in json] - return query.filter(TZH.id_sdage.in_(ids)) + return query.where(TZH.id_sdage.in_(ids)) def filter_nameorcode(query, json: dict): @@ -120,19 +121,19 @@ def filter_nameorcode(query, json: dict): json = strip_accents(json) # TODO: create index with another function to make unaccent immutable unaccent_fullname = func.lower(func.unaccent(TZH.fullname)) - subquery = ( - DB.session.query(TZH.id_zh, func.similarity(unaccent_fullname, json).label("idx_trgm")) - .filter(unaccent_fullname.ilike("%" + json + "%")) + subq = ( + select(TZH.id_zh, func.similarity(unaccent_fullname, json).label("idx_trgm")) + .where(unaccent_fullname.ilike("%" + json + "%")) .order_by(desc("idx_trgm")) .subquery() ) - return query.filter(TZH.id_zh == subquery.c.id_zh) + return query.where(TZH.id_zh == subq.c.id_zh) return query def filter_ensemble(query, json: dict): ids = [obj.get("id_site_space") for obj in json] - return query.filter(TZH.id_site_space.in_(ids)) + return query.where(TZH.id_site_space.in_(ids)) def filter_area_size(query, json: dict): @@ -143,11 +144,11 @@ def filter_area_size(query, json: dict): # TZH.area is already in ha if symbol == "=": - query = query.filter(TZH.area == ha) + query = query.where(TZH.area == ha) elif symbol == "≥": - query = query.filter(TZH.area >= ha) + query = query.where(TZH.area >= ha) elif symbol == "≤": - query = query.filter(TZH.area <= ha) + query = query.where(TZH.area <= ha) return query @@ -159,17 +160,17 @@ def filter_area(query, json: dict, type_code: str): # Filter on departments subquery = ( - DB.session.query(LAreas) - .with_entities(LAreas.area_name, LAreas.geom, LAreas.id_type, BibAreasTypes.type_code) + select(LAreas) + .with_only_columns(LAreas.area_name, LAreas.geom, LAreas.id_type, BibAreasTypes.type_code) .join(BibAreasTypes, LAreas.id_type == BibAreasTypes.id_type) - .filter(BibAreasTypes.type_code == type_code) - .filter(LAreas.area_code.in_(codes)) + .where(BibAreasTypes.type_code == type_code) + .where(LAreas.area_code.in_(codes)) .subquery() ) # Filter on geom. # Need to use (c) on subquery to get the column - query = query.filter( + query = query.where( func.ST_Transform(func.ST_SetSRID(TZH.geom, 4326), 2154).ST_Intersects(subquery.c.geom) ) @@ -181,14 +182,14 @@ def filter_hydro(query, json): if codes and all(code is not None for code in codes): subquery = ( - DB.session.query(THydroArea) - .with_entities(THydroArea.id_hydro, THydroArea.geom) - .filter(THydroArea.id_hydro.in_(codes)) + select(THydroArea) + .with_only_columns(THydroArea.id_hydro, THydroArea.geom) + .where(THydroArea.id_hydro.in_(codes)) .subquery() ) # SET_SRID does not return a valid geom... - query = query.filter( + query = query.where( func.ST_Transform(func.ST_SetSRID(TZH.geom, 4326), 4326).ST_Intersects(subquery.c.geom) ) @@ -200,16 +201,16 @@ def filter_basin(query, json): if codes is not None: subquery = ( - DB.session.query(TRiverBasin) - .with_entities( + select(TRiverBasin) + .with_only_columns( TRiverBasin.id_rb, TRiverBasin.geom, ) - .filter(TRiverBasin.id_rb.in_(codes)) + .where(TRiverBasin.id_rb.in_(codes)) .subquery() ) # SET_SRID does not return a valid geom... - query = query.filter( + query = query.where( func.ST_Transform(func.ST_SetSRID(TZH.geom, 4326), 4326).ST_Intersects(subquery.c.geom) ) @@ -233,8 +234,8 @@ def filter_fct(query, json: dict, type_: str): ids_conn = [f.get("id_nomenclature") for f in json.get("connaissances", [])] subquery = ( - DB.session.query(TFunctions.id_zh) - .with_entities( + select(TFunctions.id_zh) + .with_only_columns( TFunctions.id_zh, TFunctions.id_function, TFunctions.id_qualification, @@ -245,19 +246,19 @@ def filter_fct(query, json: dict, type_: str): ) .join(TFunctions, TFunctions.id_zh == TZH.id_zh) .join(TNomenclatures, TNomenclatures.id_nomenclature == TFunctions.id_function) - .filter_by(id_type=select([func.ref_nomenclatures.get_id_nomenclature_type(type_)])) + .filter_by(id_type=select(func.ref_nomenclatures.get_id_nomenclature_type(type_))) ) if ids_fct and all(id_ is not None for id_ in ids_fct): - subquery = subquery.filter(TFunctions.id_function.in_(ids_fct)) + subquery = subquery.where(TFunctions.id_function.in_(ids_fct)) if ids_qual and all(id_ is not None for id_ in ids_qual): - subquery = subquery.filter(TFunctions.id_qualification.in_(ids_qual)) + subquery = subquery.where(TFunctions.id_qualification.in_(ids_qual)) if ids_conn and all(id_ is not None for id_ in ids_conn): - subquery = subquery.filter(TFunctions.id_knowledge.in_(ids_conn)) + subquery = subquery.where(TFunctions.id_knowledge.in_(ids_conn)) - query = query.filter(TZH.id_zh == subquery.subquery().c.id_zh).distinct() + query = query.where(TZH.id_zh == subquery.subquery().c.id_zh).distinct() return query @@ -267,11 +268,11 @@ def filter_statuts(query, json: dict): if ids_statuts: subquery = ( - DB.session.query(TOwnership.id_zh) - .with_entities(TOwnership.id_zh, TOwnership.id_status) - .filter(TOwnership.id_status.in_(ids_statuts)) + select(TOwnership.id_zh) + .with_only_columns(TOwnership.id_zh, TOwnership.id_status) + .where(TOwnership.id_status.in_(ids_statuts)) ) - query = query.filter(TZH.id_zh == subquery.subquery().c.id_zh).distinct() + query = query.where(TZH.id_zh == subquery.subquery().c.id_zh).distinct() return query @@ -281,8 +282,8 @@ def filter_plans(query, json: dict): if ids_plans and all(id_ is not None for id_ in ids_plans): subquery = ( - DB.session.query(TManagementStructures.id_zh) - .with_entities( + select(TManagementStructures.id_zh) + .with_only_columns( TManagementPlans.id_nature, TManagementPlans.id_structure, TManagementStructures.id_structure, @@ -292,10 +293,10 @@ def filter_plans(query, json: dict): TManagementStructures, TManagementPlans.id_structure == TManagementStructures.id_structure, ) - .filter(TManagementPlans.id_nature.in_(ids_plans)) + .where(TManagementPlans.id_nature.in_(ids_plans)) ) - query = query.filter(TZH.id_zh == subquery.subquery().c.id_zh).distinct() + query = query.where(TZH.id_zh == subquery.subquery().c.id_zh).distinct() return query @@ -303,7 +304,7 @@ def filter_plans(query, json: dict): def filter_strategies(query, json: dict): ids_strategies = [f.get("id_nomenclature") for f in json.get("strategies", [])] if ids_strategies: - query = query.filter(TZH.id_strat_gestion.in_(ids_strategies)).distinct() + query = query.where(TZH.id_strat_gestion.in_(ids_strategies)).distinct() return query @@ -313,13 +314,13 @@ def filter_evaluations(query, json: dict): ids_menaces = [f.get("id_nomenclature") for f in json.get("menaces", [])] if ids_hydros and all(id_ is not None for id_ in ids_hydros): - query = query.filter(TZH.id_diag_hydro.in_(ids_hydros)) + query = query.where(TZH.id_diag_hydro.in_(ids_hydros)) if ids_bios and all(id_ is not None for id_ in ids_bios): - query = query.filter(TZH.id_diag_bio.in_(ids_bios)) + query = query.where(TZH.id_diag_bio.in_(ids_bios)) if ids_menaces and all(id_ is not None for id_ in ids_menaces): - query = query.filter(TZH.id_thread.in_(ids_menaces)) + query = query.where(TZH.id_thread.in_(ids_menaces)) return query @@ -348,9 +349,9 @@ def filter_hierarchy(query, json: dict, basin: str): filters.append(TZH.id_zh.in_(subquery)) if not and_: - query = query.filter(or_(*filters)) + query = query.where(or_(*filters)) else: - query = query.filter(*filters) + query = query.where(*filters) return query @@ -374,6 +375,7 @@ def generate_global_attributes_subquery(attributes: list, global_notes: dict): """ Generates the subquery taking care only on "GlobalMarks" """ + # TODO: sqlalchemy1.4 subquery = DB.session.query(CorZhNotes.id_zh) note_query = func.sum(CorZhNotes.note) @@ -405,6 +407,7 @@ def generate_global_attributes_subquery(attributes: list, global_notes: dict): def generate_volet(subquery, volet: str, attribute_list: list, global_notes: dict, note_query): + # TODO: sqlalchemy1.4 if volet.lower() in [VOLET1.lower(), VOLET2.lower()]: subquery = subquery.join(BibHierPanes, BibHierPanes.pane_id == TRules.pane_id).filter( BibHierPanes.label == volet @@ -426,6 +429,7 @@ def generate_volet_subquery(subquery, volet, attribute_list: list, global_notes: """ Subquery for "volet" """ + # TODO: sqlalchemy1.4 volet_nb = COR_VOLET[volet] max_note = global_notes[volet_nb] and_query = [] @@ -439,6 +443,7 @@ def generate_volet_subquery(subquery, volet, attribute_list: list, global_notes: def generate_rub(subquery, rub: str, attribute_list: list, global_notes: dict, note_query): + # TODO: sqlalchemy1.4 subquery = subquery.join(BibHierCategories, BibHierCategories.cat_id == TRules.cat_id).filter( BibHierCategories.label == rub ) @@ -495,6 +500,7 @@ def generate_rub(subquery, rub: str, attribute_list: list, global_notes: dict, n def generate_attributes_subquery(attributes: list): + # TODO: sqlalchemy1.4 subquery = DB.session.query(CorZhNotes.id_zh) attribute_ids = [] note_type_ids = [] diff --git a/backend/gn_module_zh/upload.py b/backend/gn_module_zh/upload.py index bc3e4ce6..7f76b04a 100644 --- a/backend/gn_module_zh/upload.py +++ b/backend/gn_module_zh/upload.py @@ -4,6 +4,7 @@ from geonature.core.gn_commons.models import TMedias from geonature.utils.env import DB, ROOT_DIR +from sqlalchemy.sql import update, select from werkzeug.utils import secure_filename from .api_error import ZHApiError @@ -101,8 +102,8 @@ def upload(request, extensions, pdf_size, jpg_size, upload_path, module_name, id return {"error": "ERROR_WHILE_LOADING_FILE"} # update TMedias.media_path with media_filename - DB.session.query(TMedias).filter(TMedias.id_media == id_media).update( - {"media_path": str(media_path)} + DB.session.execute( + update(TMedias).where(TMedias.id_media == id_media).values(media_path=str(media_path)) ) update_file_extension(id_media, extension) @@ -113,7 +114,8 @@ def upload(request, extensions, pdf_size, jpg_size, upload_path, module_name, id "file_name": get_file_path(id_media).name, "full_path": str(get_file_path(id_media)), "media_path": getattr( - DB.session.query(TMedias).filter(TMedias.id_media == id_media).one(), "media_path" + DB.session.execute(select(TMedias).where(TMedias.id_media == id_media)).scalar_one(), + "media_path", ), "extension": get_extension(get_file_path(id_media).name), } diff --git a/backend/gn_module_zh/utils.py b/backend/gn_module_zh/utils.py index d16d8785..c411c5b6 100644 --- a/backend/gn_module_zh/utils.py +++ b/backend/gn_module_zh/utils.py @@ -7,6 +7,7 @@ from geonature.utils.env import DB, ROOT_DIR from pypnnomenclature.models import TNomenclatures from sqlalchemy.orm import Query +from sqlalchemy.sql import select, update, delete, func from .api_error import ZHApiError from .model.zh_schema import TZH, BibAreasTypes, LAreas @@ -18,12 +19,14 @@ def get_main_picture_id(id_zh, media_list=None): media_list(list): media_list of the zh to set the main_pict_id if not present """ - main_pict_id = DB.session.query(TZH).filter(TZH.id_zh == id_zh).one().main_pict_id + main_pict_id = ( + DB.session.execute(select(TZH).where(TZH.id_zh == id_zh)).scalar_one().main_pict_id + ) if main_pict_id is None and media_list is not None and len(media_list) > 0: id_media = media_list[0].id_media - DB.session.query(TZH).filter(TZH.id_zh == id_zh).update({TZH.main_pict_id: id_media}) + stmt = update(TZH).where(TZH.id_zh == id_zh).values(main_pict_id=id_media) + DB.session.execute(stmt) DB.session.commit() - main_pict_id = id_media return main_pict_id @@ -36,16 +39,16 @@ def get_last_pdf_export(id_zh, last_date) -> Query: # TODO: Add with entities ? # Need to have do a separate query instead of reusing get_medias... query = ( - DB.session.query(TZH, TMedias, TNomenclatures) - .with_entities(TMedias.id_media) - .filter(TZH.id_zh == id_zh) - .filter(TZH.zh_uuid == TMedias.unique_id_media) - .filter(TMedias.id_nomenclature_media_type == TNomenclatures.id_nomenclature) - .filter(TNomenclatures.mnemonique == "PDF") - .filter(TMedias.meta_update_date > last_date) - .filter(TMedias.title_fr.like(f"{id_zh}_fiche%.pdf")) + select(TZH, TMedias, TNomenclatures) + .with_only_columns(TMedias.id_media) + .where(TZH.id_zh == id_zh) + .where(TZH.zh_uuid == TMedias.unique_id_media) + .where(TMedias.id_nomenclature_media_type == TNomenclatures.id_nomenclature) + .where(TNomenclatures.mnemonique == "PDF") + .where(TMedias.meta_update_date > last_date) + .where(TMedias.title_fr.like(f"{id_zh}_fiche%.pdf")) ) - return query.first() + return DB.session.execute(query).first() def get_file_path(id_media): @@ -61,7 +64,7 @@ def get_file_path(id_media): def get_media_path(id_media): try: - return DB.session.query(TMedias).filter(TMedias.id_media == id_media).one().media_path + return DB.session.get(TMedias, id_media).media_path except Exception as e: exc_type, value, tb = sys.exc_info() raise ZHApiError( @@ -76,7 +79,8 @@ def delete_file(id_media): os.remove(get_file_path(id_media)) except: pass - DB.session.query(TMedias).filter(TMedias.id_media == id_media).delete() + stmt = delete(TMedias).where(TMedias.id_media == id_media) + DB.session.execute(stmt) DB.session.commit() except Exception as e: exc_type, value, tb = sys.exc_info() @@ -88,13 +92,17 @@ def delete_file(id_media): def check_ref_geo_schema(): try: id_type_com = ( - DB.session.query(BibAreasTypes).filter(BibAreasTypes.type_code == "COM").one().id_type + DB.session.execute(select(BibAreasTypes).where(BibAreasTypes.type_code == "COM")) + .scalar_one() + .id_type ) id_type_dep = ( - DB.session.query(BibAreasTypes).filter(BibAreasTypes.type_code == "DEP").one().id_type + DB.session.execute(select(BibAreasTypes).where(BibAreasTypes.type_code == "DEP")) + .scalar_one() + .id_type ) - n_com = DB.session.query(LAreas).filter(LAreas.id_type == id_type_com).count() - n_dep = DB.session.query(LAreas).filter(LAreas.id_type == id_type_dep).count() + n_com = DB.session.scalar(select(func.count()).where(LAreas.id_type == id_type_com)) + n_dep = DB.session.scalar(select(func.count()).where(LAreas.id_type == id_type_dep)) if n_com == 0 or n_dep == 0: return False return True From 318d78c45bf18359e09b37e022e58458871fa070 Mon Sep 17 00:00:00 2001 From: Julien Corny Date: Fri, 5 Apr 2024 17:42:57 +0200 Subject: [PATCH 02/10] sqlalchemy update for hierarchy and river basins --- backend/gn_module_zh/hierarchy.py | 20 +++++++++----------- backend/gn_module_zh/model/zh_schema.py | 6 +++--- backend/gn_module_zh/search.py | 21 ++++++++------------- 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/backend/gn_module_zh/hierarchy.py b/backend/gn_module_zh/hierarchy.py index e769e321..87b14265 100644 --- a/backend/gn_module_zh/hierarchy.py +++ b/backend/gn_module_zh/hierarchy.py @@ -253,7 +253,7 @@ def __get_qualif_heritage(self): if not nb: nb = 0 try: - qualif = DB.session.scalars( + qualif = DB.session.execute( select(CorRbRules, TItems, CorItemValue) .join(TItems, TItems.cor_rule_id == CorRbRules.cor_rule_id) .join(CorItemValue, TItems.attribute_id == CorItemValue.attribute_id) @@ -602,7 +602,7 @@ def __get_qualif_management(self): ) ) ) - .scalar_one() + .all()[0] .TNomenclatures, "id_nomenclature", ) @@ -887,12 +887,12 @@ def __get_rule_name(self): try: return ( DB.session.execute( - select(TRules, BibHierSubcategories) + select(TRules, BibHierCategories) .join(TRules) .where(TRules.rule_id == self.rule_id) ) - .scalar_one() - .BibHierSubcategories.label.capitalize() + .all()[0] + .BibHierCategories.label.capitalize() ) except NoResultFound: pass @@ -902,7 +902,7 @@ def __get_rule_name(self): .join(TRules) .where(TRules.rule_id == self.rule_id) ) - .scalar_one() + .all()[0] .BibHierCategories.label.capitalize() ) @@ -920,9 +920,7 @@ def __get_knowledge_mnemo(self): TNomenclatures.id_nomenclature == BibNoteTypes.id_knowledge, ) .where(BibNoteTypes.note_id == self.knowledge) - ) - .scalar_one() - .TNomenclatures, + ).scalar_one(), "mnemonique", ) except Exception as e: @@ -1214,7 +1212,7 @@ def __get_rb(self): select(CorZhRb, TRiverBasin).join(TRiverBasin).where(CorZhRb.id_zh == self.id_zh) ) .scalar_one() - .TRiverBasin.id_rb + .id_rb ) def __check_if_rules(self): @@ -1284,7 +1282,7 @@ def get_all_hierarchy_fields(id_rb: int): tableName="all_rb_rules", schemaName="pr_zh", filters={"id_rb": id_rb, "orderby": "name"}, - limit=-1, + limit=100000, ) results = query.return_query() diff --git a/backend/gn_module_zh/model/zh_schema.py b/backend/gn_module_zh/model/zh_schema.py index 7a678cd5..cf697373 100644 --- a/backend/gn_module_zh/model/zh_schema.py +++ b/backend/gn_module_zh/model/zh_schema.py @@ -280,19 +280,19 @@ def get_tzh_by_id(id): @staticmethod def get_zh_area_intersected(zh_area_type, id_zh_geom): if zh_area_type == "river_basin": - q = DB.session.execute( + q = DB.session.scalars( select(TRiverBasin).where( TRiverBasin.geom.ST_Intersects(cast(id_zh_geom, Geography)) ) ).all() if zh_area_type == "hydro_area": - q = DB.session.execute( + q = DB.session.scalars( select(THydroArea).where( THydroArea.geom.ST_Intersects(cast(id_zh_geom, Geography)) ) ).all() if zh_area_type == "fct_area": - q = DB.session.execute( + q = DB.session.scalars( select(TFctArea).where(TFctArea.geom.ST_Intersects(cast(id_zh_geom, Geography))) ).all() return q diff --git a/backend/gn_module_zh/search.py b/backend/gn_module_zh/search.py index a97dbe03..ee2a7b14 100644 --- a/backend/gn_module_zh/search.py +++ b/backend/gn_module_zh/search.py @@ -375,8 +375,7 @@ def generate_global_attributes_subquery(attributes: list, global_notes: dict): """ Generates the subquery taking care only on "GlobalMarks" """ - # TODO: sqlalchemy1.4 - subquery = DB.session.query(CorZhNotes.id_zh) + subquery = select(CorZhNotes.id_zh) note_query = func.sum(CorZhNotes.note) subquery = subquery.join(CorRbRules, CorRbRules.cor_rule_id == CorZhNotes.cor_rule_id).join( @@ -407,9 +406,8 @@ def generate_global_attributes_subquery(attributes: list, global_notes: dict): def generate_volet(subquery, volet: str, attribute_list: list, global_notes: dict, note_query): - # TODO: sqlalchemy1.4 if volet.lower() in [VOLET1.lower(), VOLET2.lower()]: - subquery = subquery.join(BibHierPanes, BibHierPanes.pane_id == TRules.pane_id).filter( + subquery = subquery.join(BibHierPanes, BibHierPanes.pane_id == TRules.pane_id).where( BibHierPanes.label == volet ) subquery = generate_volet_subquery( @@ -429,7 +427,6 @@ def generate_volet_subquery(subquery, volet, attribute_list: list, global_notes: """ Subquery for "volet" """ - # TODO: sqlalchemy1.4 volet_nb = COR_VOLET[volet] max_note = global_notes[volet_nb] and_query = [] @@ -443,8 +440,7 @@ def generate_volet_subquery(subquery, volet, attribute_list: list, global_notes: def generate_rub(subquery, rub: str, attribute_list: list, global_notes: dict, note_query): - # TODO: sqlalchemy1.4 - subquery = subquery.join(BibHierCategories, BibHierCategories.cat_id == TRules.cat_id).filter( + subquery = subquery.join(BibHierCategories, BibHierCategories.cat_id == TRules.cat_id).where( BibHierCategories.label == rub ) # Takes care of the several attributes choosen by the user. @@ -500,8 +496,7 @@ def generate_rub(subquery, rub: str, attribute_list: list, global_notes: dict, n def generate_attributes_subquery(attributes: list): - # TODO: sqlalchemy1.4 - subquery = DB.session.query(CorZhNotes.id_zh) + subquery = select(CorZhNotes.id_zh) attribute_ids = [] note_type_ids = [] cor_rule_ids = [] @@ -514,10 +509,10 @@ def generate_attributes_subquery(attributes: list): # TODO: see if all of these are usefull... Are cor_rule_id with note sufficient? subquery = ( - subquery.filter(CorZhNotes.attribute_id.in_(attribute_ids)) - .filter(CorZhNotes.note_type_id.in_(note_type_ids)) - .filter(CorZhNotes.cor_rule_id.in_(cor_rule_ids)) - .filter(CorZhNotes.note.in_(notes)) + subquery.where(CorZhNotes.attribute_id.in_(attribute_ids)) + .where(CorZhNotes.note_type_id.in_(note_type_ids)) + .where(CorZhNotes.cor_rule_id.in_(cor_rule_ids)) + .where(CorZhNotes.note.in_(notes)) ) return subquery.subquery() From f53ed6d6d8d837e3b4f184cbc8bdc9d835de72f7 Mon Sep 17 00:00:00 2001 From: Julien Corny Date: Tue, 9 Apr 2024 23:26:07 +0200 Subject: [PATCH 03/10] fix sqlalchemy update errors for river_basins --- backend/gn_module_zh/geometry.py | 4 ++-- backend/gn_module_zh/model/zh_schema.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/gn_module_zh/geometry.py b/backend/gn_module_zh/geometry.py index 3742036a..cc2d748e 100644 --- a/backend/gn_module_zh/geometry.py +++ b/backend/gn_module_zh/geometry.py @@ -80,12 +80,12 @@ def get_main_rb(query: list) -> int: area = 0 for q_ in query: zh_polygon = ( - DB.session.scalars(select(TZH.geom).where(TZH.id_zh == getattr(q_, "id_zh"))) + DB.session.execute(select(TZH.geom).where(TZH.id_zh == getattr(q_, "id_zh"))) .first() .geom ) rb_polygon = ( - DB.session.scalar( + DB.session.execute( select(CorZhRb, TRiverBasin) .join(TRiverBasin, TRiverBasin.id_rb == CorZhRb.id_rb) .where(TRiverBasin.id_rb == getattr(q_, "id_rb")) diff --git a/backend/gn_module_zh/model/zh_schema.py b/backend/gn_module_zh/model/zh_schema.py index cf697373..40e97dfd 100644 --- a/backend/gn_module_zh/model/zh_schema.py +++ b/backend/gn_module_zh/model/zh_schema.py @@ -378,7 +378,7 @@ def get_id_types_ref_geo(id_zh, ref_geo_config): @staticmethod def get_ref_geo_info(id_zh, id_types): return [ - DB.session.scalars( + DB.session.execute( select(CorZhArea, LAreas, TZH) .join(LAreas) .where(CorZhArea.id_zh == id_zh, LAreas.id_type == id_type, TZH.id_zh == id_zh) From aa39485f5c307951df3768e9a09cf3ed30bd8c0c Mon Sep 17 00:00:00 2001 From: Julien Corny Date: Tue, 9 Apr 2024 23:59:43 +0200 Subject: [PATCH 04/10] fix duplicate results in cor_ch_status request --- backend/gn_module_zh/model/cards.py | 4 +++- backend/gn_module_zh/nomenclatures.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/backend/gn_module_zh/model/cards.py b/backend/gn_module_zh/model/cards.py index 7f63bc02..cc0a6c80 100644 --- a/backend/gn_module_zh/model/cards.py +++ b/backend/gn_module_zh/model/cards.py @@ -392,7 +392,9 @@ def __str__(self): cahier_lb_hab_fr = cahier.lb_hab_fr cahier_lb_code = cahier.lb_code priority = ( - DB.session.execute(select(CorChStatus).where(CorChStatus.lb_code == cahier_lb_code)) + DB.session.execute( + select(CorChStatus).where(CorChStatus.lb_code == cahier_lb_code).distinct() + ) .scalar_one() .priority ) diff --git a/backend/gn_module_zh/nomenclatures.py b/backend/gn_module_zh/nomenclatures.py index eaf3e08e..cfab354a 100644 --- a/backend/gn_module_zh/nomenclatures.py +++ b/backend/gn_module_zh/nomenclatures.py @@ -99,7 +99,7 @@ def get_ch(lb_code): "lb_code": hab.lb_code, "lb_hab_fr": hab.lb_hab_fr, "priority": DB.session.execute( - select(CorChStatus).where(CorChStatus.lb_code == hab.lb_code) + select(CorChStatus).where(CorChStatus.lb_code == hab.lb_code).distinct() ) .scalar_one() .priority, From 2d03683c1d837250ebbcb9a1aa2e6d461b87224e Mon Sep 17 00:00:00 2001 From: Julien Corny Date: Wed, 17 Apr 2024 23:17:36 +0200 Subject: [PATCH 05/10] sqlalchemy 1.4 review corrections --- backend/gn_module_zh/blueprint.py | 17 ++- backend/gn_module_zh/forms.py | 65 ++++------ backend/gn_module_zh/hierarchy.py | 160 ++++++++---------------- backend/gn_module_zh/model/cards.py | 39 +++--- backend/gn_module_zh/model/zh.py | 3 +- backend/gn_module_zh/model/zh_schema.py | 18 ++- backend/gn_module_zh/nomenclatures.py | 47 +++---- backend/gn_module_zh/upload.py | 5 +- backend/gn_module_zh/utils.py | 22 ++-- 9 files changed, 135 insertions(+), 241 deletions(-) diff --git a/backend/gn_module_zh/blueprint.py b/backend/gn_module_zh/blueprint.py index 153e775c..3e2a3f0b 100644 --- a/backend/gn_module_zh/blueprint.py +++ b/backend/gn_module_zh/blueprint.py @@ -125,7 +125,7 @@ def get_all_zh(info_role, query, limit, page, orderby=None, order="asc"): # try: # Pour obtenir le nombre de résultat de la requete sans le LIMIT nb_results_without_limit = ( - DB.session.execute(select(func.count()).select_from(query.subquery())).scalars().one() + DB.session.scalar(select(func.count()).select_from(query.subquery())) ) user = info_role user_cruved = get_user_cruved() @@ -155,8 +155,7 @@ def get_all_zh(info_role, query, limit, page, orderby=None, order="asc"): # Order by id because there can be ambiguity in order_by(col) depending # on the column so add on order_by id makes it clearer data = ( - DB.session.execute(query.order_by(TZH.id_zh).limit(limit).offset(page * limit)) - .scalars() + DB.session.scalars(query.order_by(TZH.id_zh).limit(limit).offset(page * limit)) .all() ) is_ref_geo = check_ref_geo_schema() @@ -370,7 +369,7 @@ def get_pbf_complete(): 'bassin_versant', tz.bassin_versant) as json_arrays FROM pr_zh.atlas_app tz) AS q; """ - row = DB.session.execute(sql).first() + row = DB.session.execute(text(sql).limit(1)).first() return Response(bytes(row["pbf"]) if row["pbf"] else bytes(), mimetype="application/protobuf") @@ -390,7 +389,7 @@ def get_json(): ) AS feature FROM (SELECT * FROM pr_zh.atlas_app tz) inputs) features; """ - row = DB.session.execute(sql).first() + row = DB.session.execute(text(sql).limit(1)).first() return row["geojson"] @@ -463,7 +462,7 @@ def get_file_list(id_zh): """get a list of the zh files contained in static repo""" try: # FIXME: to optimize... See relationships and lazy join with sqlalchemy - zh_uuid = DB.session.execute(select(TZH).where(TZH.id_zh == id_zh)).scalar_one().zh_uuid + zh_uuid = DB.session.execute(select(TZH.zh_uuid).where(TZH.id_zh == id_zh)).scalar_one() q_medias = DB.session.execute( select(TMedias, TNomenclatures.label_default) .join( @@ -773,7 +772,7 @@ def deleteOneZh(id_zh): # delete criteres delim id_lim_list = ( - DB.session.execute(select(TZH).where(TZH.id_zh == id_zh)).scalar_one().id_lim_list + DB.session.execute(select(TZH.id_lim_list).where(TZH.id_zh == id_zh)).scalar_one() ) DB.session.execute(delete(CorLimList).where(CorLimList.id_lim_list == id_lim_list)) @@ -781,7 +780,7 @@ def deleteOneZh(id_zh): DB.session.execute(delete(CorZhArea).where(CorZhArea.id_zh == id_zh)) # delete files in TMedias and repos - zh_uuid = DB.session.execute(select(TZH).where(TZH.id_zh == id_zh)).scalar_one().zh_uuid + zh_uuid = DB.session.execute(select(TZH.zh_uuid).where(TZH.id_zh == id_zh)).scalar_one() q_medias = DB.session.scalars(select(TMedias).where(TMedias.unique_id_media == zh_uuid)).all() for media in q_medias: delete_file(media.id_media) @@ -807,7 +806,7 @@ def write_csv(id_zh): names = [] FILE_PATH = blueprint.config["file_path"] MODULE_NAME = blueprint.config["MODULE_CODE"].lower() - zh_code = DB.session.execute(select(TZH).where(TZH.id_zh == id_zh)).scalar_one().code + zh_code = DB.session.execute(select(TZH.code).where(TZH.id_zh == id_zh)).scalar_one() # author name user = DB.session.execute( select(User).where(User.id_role == g.current_user.id_role) diff --git a/backend/gn_module_zh/forms.py b/backend/gn_module_zh/forms.py index ec8b7342..c6ce98b7 100644 --- a/backend/gn_module_zh/forms.py +++ b/backend/gn_module_zh/forms.py @@ -86,17 +86,15 @@ def create_zh(form_data, info_role, zh_date, polygon, zh_area, ref_geo_referenti post_cor_zh_area( polygon, new_zh.id_zh, - DB.session.execute(select(BibAreasTypes).where(BibAreasTypes.type_code == "COM")) - .scalar_one() - .id_type, + DB.session.execute(select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "COM")) + .scalar_one(), ) # fill cor_zh_area for departements post_cor_zh_area( polygon, new_zh.id_zh, - DB.session.execute(select(BibAreasTypes).where(BibAreasTypes.type_code == "DEP")) - .scalar_one() - .id_type, + DB.session.execute(select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "DEP")) + .scalar_one(), ) # fill cor_zh_area for other geo referentials for ref in ref_geo_referentiels: @@ -104,10 +102,9 @@ def create_zh(form_data, info_role, zh_date, polygon, zh_area, ref_geo_referenti polygon, new_zh.id_zh, DB.session.execute( - select(BibAreasTypes).where(BibAreasTypes.type_code == ref["type_code_ref_geo"]) + select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == ref["type_code_ref_geo"]) ) - .scalar_one() - .id_type, + .scalar_one(), ) # fill cor_zh_rb @@ -123,12 +120,11 @@ def create_zh(form_data, info_role, zh_date, polygon, zh_area, ref_geo_referenti # set default values fct_delim_default_id = ( DB.session.execute( - select(DefaultsNomenclaturesValues).where( + select(DefaultsNomenclaturesValues.id_nomenclature).where( DefaultsNomenclaturesValues.mnemonique_type == "CRIT_DEF_ESP_FCT" ) ) .scalar_one() - .id_nomenclature ) post_fct_delim(new_zh.id_zh, [fct_delim_default_id]) @@ -354,16 +350,14 @@ def update_cor_zh_area(polygon, id_zh, geo_refs): post_cor_zh_area( polygon, id_zh, - DB.session.execute(select(BibAreasTypes).where(BibAreasTypes.type_code == "COM")) - .scalar_one() - .id_type, + DB.session.execute(select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "COM")) + .scalar_one(), ) post_cor_zh_area( polygon, id_zh, - DB.session.execute(select(BibAreasTypes).where(BibAreasTypes.type_code == "DEP")) - .scalar_one() - .id_type, + DB.session.execute(select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "DEP")) + .scalar_one(), ) # fill cor_zh_area for other geo referentials for ref in geo_refs: @@ -371,12 +365,11 @@ def update_cor_zh_area(polygon, id_zh, geo_refs): polygon, id_zh, DB.session.execute( - select(BibAreasTypes).where( + select(BibAreasTypes.id_type).where( BibAreasTypes.type_code == ref["type_code_ref_geo"] ) ) - .scalar_one() - .id_type, + .scalar_one(), ) except Exception as e: if e.__class__.__name__ == "DataError": @@ -777,15 +770,14 @@ def post_managements(id_zh, managements): TManagementPlans( id_nature=plan["id_nature"], id_structure=DB.session.execute( - select(TManagementStructures).where( + select(TManagementStructures.id_structure).where( and_( TManagementStructures.id_zh == id_zh, TManagementStructures.id_org == management["structure"], ) ) ) - .scalar_one() - .id_structure, + .scalar_one(), plan_date=datetime.datetime.strptime(plan["plan_date"], "%d/%m/%Y"), duration=plan["duration"], remark=plan["remark"], @@ -849,12 +841,11 @@ def post_protections(id_zh, protections): DB.session.add( CorZhProtection( id_protection=DB.session.execute( - select(CorProtectionLevelType).where( + select(CorProtectionLevelType.id_protection).where( CorProtectionLevelType.id_protection_status == protection ) ) - .scalar_one() - .id_protection, + .scalar_one(), id_zh=id_zh, ) ) @@ -913,12 +904,11 @@ def post_urban_docs(id_zh, urban_docs): for urban_doc in urban_docs: id_doc_type = ( DB.session.execute( - select(CorUrbanTypeRange).where( + select(CorUrbanTypeRange.id_doc_type).where( CorUrbanTypeRange.id_cor == urban_doc["id_urban_type"][0]["id_cor"] ) ) .scalar_one() - .id_doc_type ) uuid_doc = uuid.uuid4() DB.session.add( @@ -978,7 +968,7 @@ def post_actions(id_zh, actions): def post_file_info(id_zh, title, author, description, extension, media_path=None): try: unique_id_media = ( - DB.session.execute(select(TZH).where(TZH.id_zh == int(id_zh))).scalar_one().zh_uuid + DB.session.execute(select(TZH.zh_uuid).where(TZH.id_zh == int(id_zh))).scalar_one() ) uuid_attached_row = uuid.uuid4() if extension == ".pdf": @@ -988,13 +978,12 @@ def post_file_info(id_zh, title, author, description, extension, media_path=None else: mnemo = "Photo" id_nomenclature_media_type = ( - DB.session.execute(select(TNomenclatures).where(TNomenclatures.mnemonique == mnemo)) + DB.session.execute(select(TNomenclatures.id_nomenclature).where(TNomenclatures.mnemonique == mnemo)) .scalar_one() - .id_nomenclature ) id_table_location = ( DB.session.execute( - select(BibTablesLocation).where( + select(BibTablesLocation.id_table_location).where( and_( BibTablesLocation.schema_name == "pr_zh", BibTablesLocation.table_name == "t_zh", @@ -1002,7 +991,6 @@ def post_file_info(id_zh, title, author, description, extension, media_path=None ) ) .scalar_one() - .id_table_location ) post_date = datetime.datetime.now() DB.session.add( @@ -1023,10 +1011,9 @@ def post_file_info(id_zh, title, author, description, extension, media_path=None DB.session.commit() id_media = ( DB.session.execute( - select(TMedias).where(TMedias.uuid_attached_row == uuid_attached_row) + select(TMedias.id_media).where(TMedias.uuid_attached_row == uuid_attached_row) ) .scalar_one() - .id_media ) return id_media except Exception as e: @@ -1042,12 +1029,12 @@ def post_file_info(id_zh, title, author, description, extension, media_path=None def patch_file_info(id_zh, id_media, title, author, description): try: unique_id_media = ( - DB.session.execute(select(TZH).where(TZH.id_zh == int(id_zh))).scalar_one().zh_uuid + DB.session.execute(select(TZH.zh_uuid).where(TZH.id_zh == int(id_zh))).scalar_one() ) uuid_attached_row = uuid.uuid4() id_table_location = ( DB.session.execute( - select(BibTablesLocation).where( + select(BibTablesLocation.id_table_location).where( and_( BibTablesLocation.schema_name == "pr_zh", BibTablesLocation.table_name == "t_zh", @@ -1055,7 +1042,6 @@ def patch_file_info(id_zh, id_media, title, author, description): ) ) .scalar_one() - .id_table_location ) post_date = datetime.datetime.now() DB.session.execute( @@ -1092,9 +1078,8 @@ def update_file_extension(id_media, extension): else: mnemo = "Photo" id_nomenclature_media_type = ( - DB.session.execute(select(TNomenclatures).where(TNomenclatures.mnemonique == mnemo)) + DB.session.execute(select(TNomenclatures.id_nomenclature).where(TNomenclatures.mnemonique == mnemo)) .scalar_one() - .id_nomenclature ) DB.session.execute( update(TMedias) diff --git a/backend/gn_module_zh/hierarchy.py b/backend/gn_module_zh/hierarchy.py index 87b14265..5e444760 100644 --- a/backend/gn_module_zh/hierarchy.py +++ b/backend/gn_module_zh/hierarchy.py @@ -54,10 +54,7 @@ def __init__(self, id_zh, rb_id, abb): def __get_rule_id(self, abb): try: - return getattr( - DB.session.execute(select(TRules).where(TRules.abbreviation == abb)).scalar_one(), - "rule_id", - ) + return DB.session.execute(select(TRules.rule_id).where(TRules.abbreviation == abb)).scalar_one() except Exception as e: exc_type, value, tb = sys.exc_info() raise ZHApiError( @@ -92,17 +89,14 @@ def __is_rb_rule(self): def __get_cor_rule_id(self): try: if self.active: - return getattr( - DB.session.execute( - select(CorRbRules).where( + return DB.session.execute( + select(CorRbRules.cor_rule_id).where( and_( CorRbRules.rb_id == self.rb_id, CorRbRules.rule_id == self.rule_id, ) ) - ).scalar_one(), - "cor_rule_id", - ) + ).scalar_one() except Exception as e: exc_type, value, tb = sys.exc_info() raise ZHApiError( @@ -159,45 +153,21 @@ def __get_nomenc_ids(self): def __get_qualif_cat7(self): try: id_nomenc = self.__get_qualif_val() - if ( - getattr( - DB.session.execute( - select(TNomenclatures).where(TNomenclatures.id_nomenclature == id_nomenc) - ).scalar_one(), - "cd_nomenclature", - ) - == "0" - ): + if DB.session.execute( + select(TNomenclatures.cd_nomenclature).where(TNomenclatures.id_nomenclature == id_nomenc) + ).scalar_one() == "0": return self.__get_id_nomenc(self.__get_id_type("HIERARCHY"), "NE") - if ( - getattr( - DB.session.execute( - select(TNomenclatures).where(TNomenclatures.id_nomenclature == id_nomenc) - ).scalar_one(), - "cd_nomenclature", - ) - == "1" - ): + if DB.session.execute( + select(TNomenclatures.cd_nomenclature).where(TNomenclatures.id_nomenclature == id_nomenc) + ).scalar_one() == "1": return self.__get_id_nomenc(self.__get_id_type("HIERARCHY"), "bon") - if ( - getattr( - DB.session.execute( - select(TNomenclatures).where(TNomenclatures.id_nomenclature == id_nomenc) - ).scalar_one(), - "cd_nomenclature", - ) - == "2" - ): + if DB.session.execute( + select(TNomenclatures.cd_nomenclature).where(TNomenclatures.id_nomenclature == id_nomenc) + ).scalar_one() == "2": return self.__get_id_nomenc(self.__get_id_type("HIERARCHY"), "moyen") - if ( - getattr( - DB.session.execute( - select(TNomenclatures).where(TNomenclatures.id_nomenclature == id_nomenc) - ).scalar_one(), - "cd_nomenclature", - ) - == "3" - ): + if DB.session.execute( + select(TNomenclatures.cd_nomenclature).where(TNomenclatures.id_nomenclature == id_nomenc) + ).scalar_one() == "3": return self.__get_id_nomenc(self.__get_id_type("HIERARCHY"), "mauvais") except ZHApiError as e: raise ZHApiError( @@ -339,29 +309,23 @@ def __get_qualif_eco(self): if len(q_functions) >= 1: # if 61 and/or 62 : get nomenc id of continum ('res') - return getattr( - DB.session.execute( - select(TNomenclatures).where( + return DB.session.execute( + select(TNomenclatures.id_nomenclature).where( and_( TNomenclatures.id_type == hier_type_id, TNomenclatures.cd_nomenclature == "res", ) ) - ).scalar_one(), - "id_nomenclature", - ) + ).scalar_one() else: - return getattr( - DB.session.execute( - select(TNomenclatures).where( + return DB.session.execute( + select(TNomenclatures.id_nomenclature).where( and_( TNomenclatures.id_type == hier_type_id, TNomenclatures.cd_nomenclature == "iso", ) ) - ).scalar_one(), - "id_nomenclature", - ) + ).scalar_one() except ZHApiError as e: raise ZHApiError( message=str(e.message), @@ -444,12 +408,9 @@ def __get_selected_functions(self, nomenc_ids): def __get_id_type(self, mnemo): try: # get id_type in TNomenclatures - return getattr( - DB.session.execute( - select(BibNomenclaturesTypes).where(BibNomenclaturesTypes.mnemonique == mnemo) - ).scalar_one(), - "id_type", - ) + return DB.session.execute( + select(BibNomenclaturesTypes.id_type).where(BibNomenclaturesTypes.mnemonique == mnemo) + ).scalar_one() except Exception as e: exc_type, value, tb = sys.exc_info() raise ZHApiError( @@ -619,29 +580,23 @@ def __get_qualif_management(self): ] if cd_id_nature_naturaliste in selected_id_nature: # if id_nature == 'naturaliste' in selected plans : return - return getattr( - DB.session.execute( - select(TNomenclatures).where( + return DB.session.execute( + select(TNomenclatures.id_nomenclature).where( and_( TNomenclatures.id_type == self.__get_id_type("HIERARCHY"), TNomenclatures.cd_nomenclature == "OUI", ) ) - ).scalar_one(), - "id_nomenclature", - ) + ).scalar_one() else: - return getattr( - DB.session.execute( - select(TNomenclatures).where( + return DB.session.execute( + select(TNomenclatures.id_nomenclature).where( and_( TNomenclatures.id_type == self.__get_id_type("HIERARCHY"), TNomenclatures.cd_nomenclature == "NON", ) ) - ).scalar_one(), - "id_nomenclature", - ) + ).scalar_one() except ZHApiError as e: raise ZHApiError( message=str(e.message), @@ -912,17 +867,14 @@ def __get_knowledge_mnemo(self): if self.knowledge == 1: return None else: - return getattr( - DB.session.execute( - select(TNomenclatures, BibNoteTypes) + return DB.session.execute( + select(TNomenclatures.mnemonique, BibNoteTypes) .join( BibNoteTypes, TNomenclatures.id_nomenclature == BibNoteTypes.id_knowledge, ) .where(BibNoteTypes.note_id == self.knowledge) - ).scalar_one(), - "mnemonique", - ) + ).scalar_one() except Exception as e: exc_type, value, tb = sys.exc_info() raise ZHApiError( @@ -933,14 +885,11 @@ def __get_knowledge_mnemo(self): def __get_qualif_mnemo(self): try: if self.active: - return getattr( - DB.session.execute( - select(TNomenclatures).where( + return DB.session.execute( + select(TNomenclatures.label_default).where( TNomenclatures.id_nomenclature == self.qualif_id ) - ).scalar_one(), - "label_default", - ) + ).scalar_one() except Exception as e: exc_type, value, tb = sys.exc_info() raise ZHApiError( @@ -980,12 +929,9 @@ def denominator(self, value): self.__denominator = Hierarchy.get_denom(self.rb_id, value) def __get_name(self): - return getattr( - DB.session.execute( - select(BibHierCategories).where(BibHierCategories.abbreviation == self.abb) - ).scalar_one(), - "label", - ) + return DB.session.execute( + select(BibHierCategories.label).where(BibHierCategories.abbreviation == self.abb) + ).scalar_one() @staticmethod def get_note(value): @@ -1207,13 +1153,9 @@ def __get_rb(self): return None if len(q_rb) > 1: return get_main_rb(q_rb) - return ( - DB.session.execute( - select(CorZhRb, TRiverBasin).join(TRiverBasin).where(CorZhRb.id_zh == self.id_zh) - ) - .scalar_one() - .id_rb - ) + return DB.session.execute( + select(CorZhRb.id_rb, TRiverBasin).join(TRiverBasin).where(CorZhRb.id_zh == self.id_zh) + ).scalar_one() def __check_if_rules(self): try: @@ -1238,15 +1180,13 @@ def __check_if_rules(self): @staticmethod def get_denom(rb_id, col_name): rb_name = ( - DB.session.execute(select(TRiverBasin).where(TRiverBasin.id_rb == rb_id)) + DB.session.execute(select(TRiverBasin.name).where(TRiverBasin.id_rb == rb_id)) .scalar_one() - .name ) - return getattr( + return ( DB.session.execute( - select(RbNotesSummary).where(RbNotesSummary.bassin_versant == rb_name) - ).scalar_one(), - col_name, + select(RbNotesSummary.col_name).where(RbNotesSummary.bassin_versant == rb_name) + ).scalar_one() ) @staticmethod @@ -1265,10 +1205,8 @@ def get_str_note(note, denominator): def as_dict(self): return { "river_basin_name": DB.session.execute( - select(TRiverBasin).where(TRiverBasin.id_rb == self.rb_id) - ) - .scalar_one() - .name, + select(TRiverBasin.name).where(TRiverBasin.id_rb == self.rb_id) + ).scalar_one(), "volet1": self.volet1.__str__(), "volet2": self.volet2.__str__(), "global_note": Hierarchy.get_str_note(self.global_note, self.total_denom), diff --git a/backend/gn_module_zh/model/cards.py b/backend/gn_module_zh/model/cards.py index cc0a6c80..50492c52 100644 --- a/backend/gn_module_zh/model/cards.py +++ b/backend/gn_module_zh/model/cards.py @@ -34,17 +34,15 @@ def get_mnemo(ids): if type(ids) is int: return ( DB.session.execute( - select(TNomenclatures).where(TNomenclatures.id_nomenclature == ids) + select(TNomenclatures.label_default).where(TNomenclatures.id_nomenclature == ids) ) .scalar_one() - .label_default ) return [ DB.session.execute( - select(TNomenclatures).where(TNomenclatures.id_nomenclature == id) + select(TNomenclatures.label_default).where(TNomenclatures.id_nomenclature == id) ) .scalar_one() - .label_default for id in ids ] return [] @@ -393,10 +391,9 @@ def __str__(self): cahier_lb_code = cahier.lb_code priority = ( DB.session.execute( - select(CorChStatus).where(CorChStatus.lb_code == cahier_lb_code).distinct() + select(CorChStatus.priority).where(CorChStatus.lb_code == cahier_lb_code).distinct() ) - .scalar_one() - .priority + .scalar_one() ) return { "biotope": biotope_lb_code + " - " + biotope_lb_hab_fr, @@ -682,10 +679,9 @@ def other_ref_geo(self, ref_geo): for i in ref: type_code = ( DB.session.execute( - select(BibAreasTypes).where(BibAreasTypes.id_type == i.LAreas.id_type) + select(BibAreasTypes.type_code).where(BibAreasTypes.id_type == i.LAreas.id_type) ) - .scalar_one() - .type_code + .scalar_one() ) refs.append( { @@ -783,10 +779,8 @@ def set_management(self, id_org, plans): def __str__(self): return { "structure": DB.session.execute( - select(BibOrganismes).where(BibOrganismes.id_org == self.id_org) - ) - .scalar_one() - .name, + select(BibOrganismes.name).where(BibOrganismes.id_org == self.id_org) + ).scalar_one(), "plans": [plan.__str__() for plan in self.plans], } @@ -825,17 +819,14 @@ def __init__(self, id_area, id_doc_type, id_cors, remark): def __str__(self): return { - "commune": DB.session.execute(select(LAreas).where(LAreas.id_area == self.id_area)) - .scalar_one() - .area_name, + "commune": DB.session.execute(select(LAreas.area_name).where(LAreas.id_area == self.id_area)) + .scalar_one(), "type_doc": Utils.get_mnemo(self.id_doc_type), "type_classement": [ Utils.get_mnemo( DB.session.execute( - select(CorUrbanTypeRange).where(CorUrbanTypeRange.id_cor == id) - ) - .scalar_one() - .id_range_type + select(CorUrbanTypeRange.id_range_type).where(CorUrbanTypeRange.id_cor == id) + ).scalar_one() ) for id in self.id_cors ], @@ -1016,10 +1007,8 @@ def __init__(self, id_action, id_priority_level, remark): def __str__(self): return { "proposition": DB.session.execute( - select(BibActions).where(BibActions.id_action == self.id_action) - ) - .scalar_one() - .name, + select(BibActions.name).where(BibActions.id_action == self.id_action) + ).scalar_one(), "niveau": Utils.get_mnemo(self.id_priority_level), "remarque": Utils.get_string(self.remark), } diff --git a/backend/gn_module_zh/model/zh.py b/backend/gn_module_zh/model/zh.py index 050801e9..57142a10 100644 --- a/backend/gn_module_zh/model/zh.py +++ b/backend/gn_module_zh/model/zh.py @@ -180,12 +180,11 @@ def get_protections(self): return { "protections": [ DB.session.execute( - select(CorProtectionLevelType).where( + select(CorProtectionLevelType.id_protection_status).where( CorProtectionLevelType.id_protection == protec ) ) .scalar_one() - .id_protection_status for protec in [ protection.id_protection for protection in ZH.get_data_by_id(CorZhProtection, self.zh.id_zh) diff --git a/backend/gn_module_zh/model/zh_schema.py b/backend/gn_module_zh/model/zh_schema.py index 40e97dfd..629ee098 100644 --- a/backend/gn_module_zh/model/zh_schema.py +++ b/backend/gn_module_zh/model/zh_schema.py @@ -268,9 +268,8 @@ def get_geofeature(self, recursif=True, relationships=()): @staticmethod def get_site_space_name(id): return ( - DB.session.execute(select(BibSiteSpace).where(BibSiteSpace.id_site_space == id)) + DB.session.execute(select(BibSiteSpace.name).where(BibSiteSpace.id_site_space == id)) .scalar_one() - .name ) @staticmethod @@ -366,12 +365,11 @@ def get_id_types_ref_geo(id_zh, ref_geo_config): if ref["active"]: ids.append( DB.session.execute( - select(BibAreasTypes).where( + select(BibAreasTypes.id_type).where( BibAreasTypes.type_code == ref["type_code_ref_geo"] ) ) .scalar_one() - .id_type ) return ids @@ -619,13 +617,13 @@ def get_all_functions(nomenc_ids): @staticmethod def get_main_function_list(ids): - # méthode utilisée ??? + # méthode utilisée ? q_id_types = DB.session.scalars(select(func.distinct(CorMainFct.id_main_function))).all() return [id[0] for id in q_id_types if id[0] in ids] @staticmethod def get_function_by_main_function(id_main): - # méthode utilisée ??? + # méthode utilisée ? return DB.session.execute( select(CorMainFct, TNomenclatures) .join(TNomenclatures, TNomenclatures.id_nomenclature == CorMainFct.id_function) @@ -634,8 +632,9 @@ def get_function_by_main_function(id_main): @staticmethod def get_mnemo_type(id_type): + # methode utilisée ? if id_type: - # pas testé + test = 'test' return DB.session.execute( select(TNomenclatures).where(TNomenclatures.id_nomenclature == id_type) ).scalar_one() @@ -798,12 +797,11 @@ def get_range_by_doc(doc_id): "id_cor": range.id_cor, "id_nomenclature": range.id_range_type, "mnemonique": DB.session.execute( - select(TNomenclatures).where( + select(TNomenclatures.mnemonique).where( TNomenclatures.id_nomenclature == range.id_range_type ) ) - .scalar_one() - .mnemonique, + .scalar_one(), } ) return ranges diff --git a/backend/gn_module_zh/nomenclatures.py b/backend/gn_module_zh/nomenclatures.py index cfab354a..a030e060 100644 --- a/backend/gn_module_zh/nomenclatures.py +++ b/backend/gn_module_zh/nomenclatures.py @@ -63,22 +63,19 @@ def get_corine_biotope(): def get_ch(lb_code): try: CH_typo = ( - DB.session.execute(select(TypoRef).where(TypoRef.cd_table == "TYPO_CH")) - .scalar_one() - .cd_typo + DB.session.execute(select(TypoRef.cd_typo).where(TypoRef.cd_table == "TYPO_CH")) + .scalar_one() ) CB_typo = ( - DB.session.execute(select(TypoRef).where(TypoRef.cd_table == "TYPO_CORINE_BIOTOPES")) + DB.session.execute(select(TypoRef.cd_typo).where(TypoRef.cd_table == "TYPO_CORINE_BIOTOPES")) .scalar_one() - .cd_typo ) # get cd_hab_sortie list from lb_code of selected Corine Biotope cd_hab_sortie = ( DB.session.execute( - select(Habref).where(and_(Habref.lb_code == lb_code, Habref.cd_typo == CB_typo)) + select(Habref.cd_hab).where(and_(Habref.lb_code == lb_code, Habref.cd_typo == CB_typo)) ) .scalar_one() - .cd_hab ) # get all cd_hab_entre corresponding to cd_hab_sortie q_cd_hab_entre = DB.session.scalars( @@ -99,10 +96,8 @@ def get_ch(lb_code): "lb_code": hab.lb_code, "lb_hab_fr": hab.lb_hab_fr, "priority": DB.session.execute( - select(CorChStatus).where(CorChStatus.lb_code == hab.lb_code).distinct() - ) - .scalar_one() - .priority, + select(CorChStatus.priority).where(CorChStatus.lb_code == hab.lb_code).distinct() + ).scalar_one() } ) return ch @@ -145,12 +140,11 @@ def get_impact_category(impact): if impact.CorImpactTypes.id_impact_type is not None: return ( DB.session.execute( - select(TNomenclatures).where( + select(TNomenclatures.mnemonique).where( TNomenclatures.id_nomenclature == impact.CorImpactTypes.id_impact_type ) ) .scalar_one() - .mnemonique ) return "Aucun" @@ -160,10 +154,9 @@ def get_function_list(mnemo): # get id_type of mnemo (ex : 'FONCTIONS_HYDRO') in BibNomenclatureTypes id_type_main_function = ( DB.session.execute( - select(BibNomenclaturesTypes).where(BibNomenclaturesTypes.mnemonique == mnemo) + select(BibNomenclaturesTypes.id_type).where(BibNomenclaturesTypes.mnemonique == mnemo) ) .scalar_one() - .id_type ) # get list of TNomenclatures ids by id_type @@ -180,12 +173,12 @@ def get_function_list(mnemo): "mnemonique": function.TNomenclatures.mnemonique, "id_category": function.CorMainFct.id_main_function, "category": DB.session.execute( - select(TNomenclatures).where( + select(TNomenclatures.mnemonique).where( TNomenclatures.id_nomenclature == function.CorMainFct.id_main_function ) ) .scalar_one() - .mnemonique.upper(), + .upper(), } for function in CorMainFct.get_functions(nomenclature_ids) ] @@ -202,10 +195,9 @@ def get_all_function_list(mnemo): # get id_type of mnemo (ex : 'FONCTIONS_HYDRO') in BibNomenclatureTypes id_type_main_function = ( DB.session.execute( - select(BibNomenclaturesTypes).where(BibNomenclaturesTypes.mnemonique == mnemo) + select(BibNomenclaturesTypes.id_type).where(BibNomenclaturesTypes.mnemonique == mnemo) ) .scalar_one() - .id_type ) # get list of TNomenclatures ids by id_type @@ -222,12 +214,12 @@ def get_all_function_list(mnemo): "mnemonique": function.TNomenclatures.mnemonique, "id_category": function.CorMainFct.id_main_function, "category": DB.session.execute( - select(TNomenclatures).where( + select(TNomenclatures.mnemonique).where( TNomenclatures.id_nomenclature == function.CorMainFct.id_main_function ) ) .scalar_one() - .mnemonique.upper(), + .upper(), } for function in CorMainFct.get_all_functions(nomenclature_ids) ] @@ -263,20 +255,18 @@ def get_protections(): { "id_protection_status": protection.id_protection_status, "mnemonique_status": DB.session.execute( - select(TNomenclatures).where( + select(TNomenclatures.mnemonique).where( TNomenclatures.id_nomenclature == protection.id_protection_status ) ) - .scalar_one() - .mnemonique, + .scalar_one(), "id_protection_level": protection.id_protection_level, "mnemonique_level": DB.session.execute( - select(TNomenclatures).where( + select(TNomenclatures.mnemonique).where( TNomenclatures.id_nomenclature == protection.id_protection_level ) ) - .scalar_one() - .mnemonique, + .scalar_one(), "category": get_protection_category(protection), "category_id": protection.id_protection_type, } @@ -296,12 +286,11 @@ def get_protection_category(protection): if protection.id_protection_type is not None: return ( DB.session.execute( - select(TNomenclatures).where( + select(TNomenclatures.mnemonique).where( TNomenclatures.id_nomenclature == protection.id_protection_type ) ) .scalar_one() - .mnemonique ) return "Autre" diff --git a/backend/gn_module_zh/upload.py b/backend/gn_module_zh/upload.py index 7f76b04a..cc4095c5 100644 --- a/backend/gn_module_zh/upload.py +++ b/backend/gn_module_zh/upload.py @@ -113,10 +113,7 @@ def upload(request, extensions, pdf_size, jpg_size, upload_path, module_name, id return { "file_name": get_file_path(id_media).name, "full_path": str(get_file_path(id_media)), - "media_path": getattr( - DB.session.execute(select(TMedias).where(TMedias.id_media == id_media)).scalar_one(), - "media_path", - ), + "media_path": DB.session.execute(select(TMedias.media_path).where(TMedias.id_media == id_media)).scalar_one(), "extension": get_extension(get_file_path(id_media).name), } diff --git a/backend/gn_module_zh/utils.py b/backend/gn_module_zh/utils.py index c411c5b6..c6534b66 100644 --- a/backend/gn_module_zh/utils.py +++ b/backend/gn_module_zh/utils.py @@ -20,7 +20,7 @@ def get_main_picture_id(id_zh, media_list=None): present """ main_pict_id = ( - DB.session.execute(select(TZH).where(TZH.id_zh == id_zh)).scalar_one().main_pict_id + DB.session.execute(select(TZH.main_pict_id).where(TZH.id_zh == id_zh)).scalar_one() ) if main_pict_id is None and media_list is not None and len(media_list) > 0: id_media = media_list[0].id_media @@ -41,12 +41,14 @@ def get_last_pdf_export(id_zh, last_date) -> Query: query = ( select(TZH, TMedias, TNomenclatures) .with_only_columns(TMedias.id_media) - .where(TZH.id_zh == id_zh) - .where(TZH.zh_uuid == TMedias.unique_id_media) - .where(TMedias.id_nomenclature_media_type == TNomenclatures.id_nomenclature) - .where(TNomenclatures.mnemonique == "PDF") - .where(TMedias.meta_update_date > last_date) - .where(TMedias.title_fr.like(f"{id_zh}_fiche%.pdf")) + .where( + TZH.id_zh == id_zh, + TZH.zh_uuid == TMedias.unique_id_media, + TMedias.id_nomenclature_media_type == TNomenclatures.id_nomenclature, + TNomenclatures.mnemonique == "PDF", + TMedias.meta_update_date > last_date, + TMedias.title_fr.like(f"{id_zh}_fiche%.pdf") + ) ) return DB.session.execute(query).first() @@ -92,14 +94,12 @@ def delete_file(id_media): def check_ref_geo_schema(): try: id_type_com = ( - DB.session.execute(select(BibAreasTypes).where(BibAreasTypes.type_code == "COM")) + DB.session.execute(select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "DEP")) .scalar_one() - .id_type ) id_type_dep = ( - DB.session.execute(select(BibAreasTypes).where(BibAreasTypes.type_code == "DEP")) + DB.session.execute(select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "DEP")) .scalar_one() - .id_type ) n_com = DB.session.scalar(select(func.count()).where(LAreas.id_type == id_type_com)) n_dep = DB.session.scalar(select(func.count()).where(LAreas.id_type == id_type_dep)) From 44474395877905d997e30520a032dec8d48632f3 Mon Sep 17 00:00:00 2001 From: Julien Corny Date: Wed, 17 Apr 2024 23:19:33 +0200 Subject: [PATCH 06/10] linter backend --- backend/gn_module_zh/blueprint.py | 15 +-- backend/gn_module_zh/forms.py | 123 ++++++++---------- backend/gn_module_zh/hierarchy.py | 159 ++++++++++++++---------- backend/gn_module_zh/model/cards.py | 43 ++++--- backend/gn_module_zh/model/zh.py | 3 +- backend/gn_module_zh/model/zh_schema.py | 15 +-- backend/gn_module_zh/nomenclatures.py | 75 +++++------ backend/gn_module_zh/upload.py | 4 +- backend/gn_module_zh/utils.py | 22 ++-- 9 files changed, 220 insertions(+), 239 deletions(-) diff --git a/backend/gn_module_zh/blueprint.py b/backend/gn_module_zh/blueprint.py index 3e2a3f0b..b96a98a8 100644 --- a/backend/gn_module_zh/blueprint.py +++ b/backend/gn_module_zh/blueprint.py @@ -124,8 +124,8 @@ def get_zh(scope): def get_all_zh(info_role, query, limit, page, orderby=None, order="asc"): # try: # Pour obtenir le nombre de résultat de la requete sans le LIMIT - nb_results_without_limit = ( - DB.session.scalar(select(func.count()).select_from(query.subquery())) + nb_results_without_limit = DB.session.scalar( + select(func.count()).select_from(query.subquery()) ) user = info_role user_cruved = get_user_cruved() @@ -154,10 +154,7 @@ def get_all_zh(info_role, query, limit, page, orderby=None, order="asc"): # Order by id because there can be ambiguity in order_by(col) depending # on the column so add on order_by id makes it clearer - data = ( - DB.session.scalars(query.order_by(TZH.id_zh).limit(limit).offset(page * limit)) - .all() - ) + data = DB.session.scalars(query.order_by(TZH.id_zh).limit(limit).offset(page * limit)).all() is_ref_geo = check_ref_geo_schema() featureCollection = [] @@ -771,9 +768,9 @@ def deleteOneZh(id_zh): DB.session.execute(delete(CorZhRef).where(CorZhRef.id_zh == id_zh)) # delete criteres delim - id_lim_list = ( - DB.session.execute(select(TZH.id_lim_list).where(TZH.id_zh == id_zh)).scalar_one() - ) + id_lim_list = DB.session.execute( + select(TZH.id_lim_list).where(TZH.id_zh == id_zh) + ).scalar_one() DB.session.execute(delete(CorLimList).where(CorLimList.id_lim_list == id_lim_list)) # delete cor_zh_area diff --git a/backend/gn_module_zh/forms.py b/backend/gn_module_zh/forms.py index c6ce98b7..a4970e62 100644 --- a/backend/gn_module_zh/forms.py +++ b/backend/gn_module_zh/forms.py @@ -86,15 +86,17 @@ def create_zh(form_data, info_role, zh_date, polygon, zh_area, ref_geo_referenti post_cor_zh_area( polygon, new_zh.id_zh, - DB.session.execute(select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "COM")) - .scalar_one(), + DB.session.execute( + select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "COM") + ).scalar_one(), ) # fill cor_zh_area for departements post_cor_zh_area( polygon, new_zh.id_zh, - DB.session.execute(select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "DEP")) - .scalar_one(), + DB.session.execute( + select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "DEP") + ).scalar_one(), ) # fill cor_zh_area for other geo referentials for ref in ref_geo_referentiels: @@ -102,9 +104,10 @@ def create_zh(form_data, info_role, zh_date, polygon, zh_area, ref_geo_referenti polygon, new_zh.id_zh, DB.session.execute( - select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == ref["type_code_ref_geo"]) - ) - .scalar_one(), + select(BibAreasTypes.id_type).where( + BibAreasTypes.type_code == ref["type_code_ref_geo"] + ) + ).scalar_one(), ) # fill cor_zh_rb @@ -118,14 +121,11 @@ def create_zh(form_data, info_role, zh_date, polygon, zh_area, ref_geo_referenti new_zh.code = code.__repr__() new_zh.ef_area = total_cover # set default values - fct_delim_default_id = ( - DB.session.execute( - select(DefaultsNomenclaturesValues.id_nomenclature).where( - DefaultsNomenclaturesValues.mnemonique_type == "CRIT_DEF_ESP_FCT" - ) + fct_delim_default_id = DB.session.execute( + select(DefaultsNomenclaturesValues.id_nomenclature).where( + DefaultsNomenclaturesValues.mnemonique_type == "CRIT_DEF_ESP_FCT" ) - .scalar_one() - ) + ).scalar_one() post_fct_delim(new_zh.id_zh, [fct_delim_default_id]) @@ -350,14 +350,16 @@ def update_cor_zh_area(polygon, id_zh, geo_refs): post_cor_zh_area( polygon, id_zh, - DB.session.execute(select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "COM")) - .scalar_one(), + DB.session.execute( + select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "COM") + ).scalar_one(), ) post_cor_zh_area( polygon, id_zh, - DB.session.execute(select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "DEP")) - .scalar_one(), + DB.session.execute( + select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "DEP") + ).scalar_one(), ) # fill cor_zh_area for other geo referentials for ref in geo_refs: @@ -368,8 +370,7 @@ def update_cor_zh_area(polygon, id_zh, geo_refs): select(BibAreasTypes.id_type).where( BibAreasTypes.type_code == ref["type_code_ref_geo"] ) - ) - .scalar_one(), + ).scalar_one(), ) except Exception as e: if e.__class__.__name__ == "DataError": @@ -776,8 +777,7 @@ def post_managements(id_zh, managements): TManagementStructures.id_org == management["structure"], ) ) - ) - .scalar_one(), + ).scalar_one(), plan_date=datetime.datetime.strptime(plan["plan_date"], "%d/%m/%Y"), duration=plan["duration"], remark=plan["remark"], @@ -844,8 +844,7 @@ def post_protections(id_zh, protections): select(CorProtectionLevelType.id_protection).where( CorProtectionLevelType.id_protection_status == protection ) - ) - .scalar_one(), + ).scalar_one(), id_zh=id_zh, ) ) @@ -902,14 +901,11 @@ def update_urban_docs(id_zh, urban_docs): def post_urban_docs(id_zh, urban_docs): for urban_doc in urban_docs: - id_doc_type = ( - DB.session.execute( - select(CorUrbanTypeRange.id_doc_type).where( - CorUrbanTypeRange.id_cor == urban_doc["id_urban_type"][0]["id_cor"] - ) + id_doc_type = DB.session.execute( + select(CorUrbanTypeRange.id_doc_type).where( + CorUrbanTypeRange.id_cor == urban_doc["id_urban_type"][0]["id_cor"] ) - .scalar_one() - ) + ).scalar_one() uuid_doc = uuid.uuid4() DB.session.add( TUrbanPlanningDocs( @@ -967,9 +963,9 @@ def post_actions(id_zh, actions): def post_file_info(id_zh, title, author, description, extension, media_path=None): try: - unique_id_media = ( - DB.session.execute(select(TZH.zh_uuid).where(TZH.id_zh == int(id_zh))).scalar_one() - ) + unique_id_media = DB.session.execute( + select(TZH.zh_uuid).where(TZH.id_zh == int(id_zh)) + ).scalar_one() uuid_attached_row = uuid.uuid4() if extension == ".pdf": mnemo = "PDF" @@ -977,21 +973,17 @@ def post_file_info(id_zh, title, author, description, extension, media_path=None mnemo = "Tableur" else: mnemo = "Photo" - id_nomenclature_media_type = ( - DB.session.execute(select(TNomenclatures.id_nomenclature).where(TNomenclatures.mnemonique == mnemo)) - .scalar_one() - ) - id_table_location = ( - DB.session.execute( - select(BibTablesLocation.id_table_location).where( - and_( - BibTablesLocation.schema_name == "pr_zh", - BibTablesLocation.table_name == "t_zh", - ) + id_nomenclature_media_type = DB.session.execute( + select(TNomenclatures.id_nomenclature).where(TNomenclatures.mnemonique == mnemo) + ).scalar_one() + id_table_location = DB.session.execute( + select(BibTablesLocation.id_table_location).where( + and_( + BibTablesLocation.schema_name == "pr_zh", + BibTablesLocation.table_name == "t_zh", ) ) - .scalar_one() - ) + ).scalar_one() post_date = datetime.datetime.now() DB.session.add( TMedias( @@ -1009,12 +1001,9 @@ def post_file_info(id_zh, title, author, description, extension, media_path=None ) ) DB.session.commit() - id_media = ( - DB.session.execute( - select(TMedias.id_media).where(TMedias.uuid_attached_row == uuid_attached_row) - ) - .scalar_one() - ) + id_media = DB.session.execute( + select(TMedias.id_media).where(TMedias.uuid_attached_row == uuid_attached_row) + ).scalar_one() return id_media except Exception as e: if e.__class__.__name__ == "DataError": @@ -1028,21 +1017,18 @@ def post_file_info(id_zh, title, author, description, extension, media_path=None def patch_file_info(id_zh, id_media, title, author, description): try: - unique_id_media = ( - DB.session.execute(select(TZH.zh_uuid).where(TZH.id_zh == int(id_zh))).scalar_one() - ) + unique_id_media = DB.session.execute( + select(TZH.zh_uuid).where(TZH.id_zh == int(id_zh)) + ).scalar_one() uuid_attached_row = uuid.uuid4() - id_table_location = ( - DB.session.execute( - select(BibTablesLocation.id_table_location).where( - and_( - BibTablesLocation.schema_name == "pr_zh", - BibTablesLocation.table_name == "t_zh", - ) + id_table_location = DB.session.execute( + select(BibTablesLocation.id_table_location).where( + and_( + BibTablesLocation.schema_name == "pr_zh", + BibTablesLocation.table_name == "t_zh", ) ) - .scalar_one() - ) + ).scalar_one() post_date = datetime.datetime.now() DB.session.execute( update(TMedias) @@ -1077,10 +1063,9 @@ def update_file_extension(id_media, extension): mnemo = "Tableur" else: mnemo = "Photo" - id_nomenclature_media_type = ( - DB.session.execute(select(TNomenclatures.id_nomenclature).where(TNomenclatures.mnemonique == mnemo)) - .scalar_one() - ) + id_nomenclature_media_type = DB.session.execute( + select(TNomenclatures.id_nomenclature).where(TNomenclatures.mnemonique == mnemo) + ).scalar_one() DB.session.execute( update(TMedias) .where(TMedias.id_media == id_media) diff --git a/backend/gn_module_zh/hierarchy.py b/backend/gn_module_zh/hierarchy.py index 5e444760..73eeac80 100644 --- a/backend/gn_module_zh/hierarchy.py +++ b/backend/gn_module_zh/hierarchy.py @@ -54,7 +54,9 @@ def __init__(self, id_zh, rb_id, abb): def __get_rule_id(self, abb): try: - return DB.session.execute(select(TRules.rule_id).where(TRules.abbreviation == abb)).scalar_one() + return DB.session.execute( + select(TRules.rule_id).where(TRules.abbreviation == abb) + ).scalar_one() except Exception as e: exc_type, value, tb = sys.exc_info() raise ZHApiError( @@ -90,13 +92,13 @@ def __get_cor_rule_id(self): try: if self.active: return DB.session.execute( - select(CorRbRules.cor_rule_id).where( - and_( - CorRbRules.rb_id == self.rb_id, - CorRbRules.rule_id == self.rule_id, - ) + select(CorRbRules.cor_rule_id).where( + and_( + CorRbRules.rb_id == self.rb_id, + CorRbRules.rule_id == self.rule_id, ) - ).scalar_one() + ) + ).scalar_one() except Exception as e: exc_type, value, tb = sys.exc_info() raise ZHApiError( @@ -153,21 +155,41 @@ def __get_nomenc_ids(self): def __get_qualif_cat7(self): try: id_nomenc = self.__get_qualif_val() - if DB.session.execute( - select(TNomenclatures.cd_nomenclature).where(TNomenclatures.id_nomenclature == id_nomenc) - ).scalar_one() == "0": + if ( + DB.session.execute( + select(TNomenclatures.cd_nomenclature).where( + TNomenclatures.id_nomenclature == id_nomenc + ) + ).scalar_one() + == "0" + ): return self.__get_id_nomenc(self.__get_id_type("HIERARCHY"), "NE") - if DB.session.execute( - select(TNomenclatures.cd_nomenclature).where(TNomenclatures.id_nomenclature == id_nomenc) - ).scalar_one() == "1": + if ( + DB.session.execute( + select(TNomenclatures.cd_nomenclature).where( + TNomenclatures.id_nomenclature == id_nomenc + ) + ).scalar_one() + == "1" + ): return self.__get_id_nomenc(self.__get_id_type("HIERARCHY"), "bon") - if DB.session.execute( - select(TNomenclatures.cd_nomenclature).where(TNomenclatures.id_nomenclature == id_nomenc) - ).scalar_one() == "2": + if ( + DB.session.execute( + select(TNomenclatures.cd_nomenclature).where( + TNomenclatures.id_nomenclature == id_nomenc + ) + ).scalar_one() + == "2" + ): return self.__get_id_nomenc(self.__get_id_type("HIERARCHY"), "moyen") - if DB.session.execute( - select(TNomenclatures.cd_nomenclature).where(TNomenclatures.id_nomenclature == id_nomenc) - ).scalar_one() == "3": + if ( + DB.session.execute( + select(TNomenclatures.cd_nomenclature).where( + TNomenclatures.id_nomenclature == id_nomenc + ) + ).scalar_one() + == "3" + ): return self.__get_id_nomenc(self.__get_id_type("HIERARCHY"), "mauvais") except ZHApiError as e: raise ZHApiError( @@ -310,22 +332,22 @@ def __get_qualif_eco(self): if len(q_functions) >= 1: # if 61 and/or 62 : get nomenc id of continum ('res') return DB.session.execute( - select(TNomenclatures.id_nomenclature).where( - and_( - TNomenclatures.id_type == hier_type_id, - TNomenclatures.cd_nomenclature == "res", - ) + select(TNomenclatures.id_nomenclature).where( + and_( + TNomenclatures.id_type == hier_type_id, + TNomenclatures.cd_nomenclature == "res", ) - ).scalar_one() + ) + ).scalar_one() else: return DB.session.execute( - select(TNomenclatures.id_nomenclature).where( - and_( - TNomenclatures.id_type == hier_type_id, - TNomenclatures.cd_nomenclature == "iso", - ) + select(TNomenclatures.id_nomenclature).where( + and_( + TNomenclatures.id_type == hier_type_id, + TNomenclatures.cd_nomenclature == "iso", ) - ).scalar_one() + ) + ).scalar_one() except ZHApiError as e: raise ZHApiError( message=str(e.message), @@ -409,8 +431,10 @@ def __get_id_type(self, mnemo): try: # get id_type in TNomenclatures return DB.session.execute( - select(BibNomenclaturesTypes.id_type).where(BibNomenclaturesTypes.mnemonique == mnemo) - ).scalar_one() + select(BibNomenclaturesTypes.id_type).where( + BibNomenclaturesTypes.mnemonique == mnemo + ) + ).scalar_one() except Exception as e: exc_type, value, tb = sys.exc_info() raise ZHApiError( @@ -581,22 +605,22 @@ def __get_qualif_management(self): if cd_id_nature_naturaliste in selected_id_nature: # if id_nature == 'naturaliste' in selected plans : return return DB.session.execute( - select(TNomenclatures.id_nomenclature).where( - and_( - TNomenclatures.id_type == self.__get_id_type("HIERARCHY"), - TNomenclatures.cd_nomenclature == "OUI", - ) + select(TNomenclatures.id_nomenclature).where( + and_( + TNomenclatures.id_type == self.__get_id_type("HIERARCHY"), + TNomenclatures.cd_nomenclature == "OUI", ) - ).scalar_one() + ) + ).scalar_one() else: return DB.session.execute( - select(TNomenclatures.id_nomenclature).where( - and_( - TNomenclatures.id_type == self.__get_id_type("HIERARCHY"), - TNomenclatures.cd_nomenclature == "NON", - ) + select(TNomenclatures.id_nomenclature).where( + and_( + TNomenclatures.id_type == self.__get_id_type("HIERARCHY"), + TNomenclatures.cd_nomenclature == "NON", ) - ).scalar_one() + ) + ).scalar_one() except ZHApiError as e: raise ZHApiError( message=str(e.message), @@ -868,13 +892,13 @@ def __get_knowledge_mnemo(self): return None else: return DB.session.execute( - select(TNomenclatures.mnemonique, BibNoteTypes) - .join( - BibNoteTypes, - TNomenclatures.id_nomenclature == BibNoteTypes.id_knowledge, - ) - .where(BibNoteTypes.note_id == self.knowledge) - ).scalar_one() + select(TNomenclatures.mnemonique, BibNoteTypes) + .join( + BibNoteTypes, + TNomenclatures.id_nomenclature == BibNoteTypes.id_knowledge, + ) + .where(BibNoteTypes.note_id == self.knowledge) + ).scalar_one() except Exception as e: exc_type, value, tb = sys.exc_info() raise ZHApiError( @@ -886,10 +910,10 @@ def __get_qualif_mnemo(self): try: if self.active: return DB.session.execute( - select(TNomenclatures.label_default).where( - TNomenclatures.id_nomenclature == self.qualif_id - ) - ).scalar_one() + select(TNomenclatures.label_default).where( + TNomenclatures.id_nomenclature == self.qualif_id + ) + ).scalar_one() except Exception as e: exc_type, value, tb = sys.exc_info() raise ZHApiError( @@ -930,8 +954,8 @@ def denominator(self, value): def __get_name(self): return DB.session.execute( - select(BibHierCategories.label).where(BibHierCategories.abbreviation == self.abb) - ).scalar_one() + select(BibHierCategories.label).where(BibHierCategories.abbreviation == self.abb) + ).scalar_one() @staticmethod def get_note(value): @@ -1154,8 +1178,8 @@ def __get_rb(self): if len(q_rb) > 1: return get_main_rb(q_rb) return DB.session.execute( - select(CorZhRb.id_rb, TRiverBasin).join(TRiverBasin).where(CorZhRb.id_zh == self.id_zh) - ).scalar_one() + select(CorZhRb.id_rb, TRiverBasin).join(TRiverBasin).where(CorZhRb.id_zh == self.id_zh) + ).scalar_one() def __check_if_rules(self): try: @@ -1179,15 +1203,12 @@ def __check_if_rules(self): @staticmethod def get_denom(rb_id, col_name): - rb_name = ( - DB.session.execute(select(TRiverBasin.name).where(TRiverBasin.id_rb == rb_id)) - .scalar_one() - ) - return ( - DB.session.execute( - select(RbNotesSummary.col_name).where(RbNotesSummary.bassin_versant == rb_name) - ).scalar_one() - ) + rb_name = DB.session.execute( + select(TRiverBasin.name).where(TRiverBasin.id_rb == rb_id) + ).scalar_one() + return DB.session.execute( + select(RbNotesSummary.col_name).where(RbNotesSummary.bassin_versant == rb_name) + ).scalar_one() @staticmethod def get_str_note(note, denominator): diff --git a/backend/gn_module_zh/model/cards.py b/backend/gn_module_zh/model/cards.py index 50492c52..85ec29e2 100644 --- a/backend/gn_module_zh/model/cards.py +++ b/backend/gn_module_zh/model/cards.py @@ -32,17 +32,17 @@ class Utils(ZH): def get_mnemo(ids): if ids: if type(ids) is int: - return ( - DB.session.execute( - select(TNomenclatures.label_default).where(TNomenclatures.id_nomenclature == ids) + return DB.session.execute( + select(TNomenclatures.label_default).where( + TNomenclatures.id_nomenclature == ids ) - .scalar_one() - ) + ).scalar_one() return [ DB.session.execute( - select(TNomenclatures.label_default).where(TNomenclatures.id_nomenclature == id) - ) - .scalar_one() + select(TNomenclatures.label_default).where( + TNomenclatures.id_nomenclature == id + ) + ).scalar_one() for id in ids ] return [] @@ -389,12 +389,9 @@ def __str__(self): ).scalar_one() cahier_lb_hab_fr = cahier.lb_hab_fr cahier_lb_code = cahier.lb_code - priority = ( - DB.session.execute( - select(CorChStatus.priority).where(CorChStatus.lb_code == cahier_lb_code).distinct() - ) - .scalar_one() - ) + priority = DB.session.execute( + select(CorChStatus.priority).where(CorChStatus.lb_code == cahier_lb_code).distinct() + ).scalar_one() return { "biotope": biotope_lb_code + " - " + biotope_lb_hab_fr, "etat": Utils.get_mnemo(self.id_preservation_state), @@ -677,12 +674,11 @@ def other_ref_geo(self, ref_geo): refs = [] for ref in CorZhArea.get_ref_geo_info(self.id_zh, id_types): for i in ref: - type_code = ( - DB.session.execute( - select(BibAreasTypes.type_code).where(BibAreasTypes.id_type == i.LAreas.id_type) + type_code = DB.session.execute( + select(BibAreasTypes.type_code).where( + BibAreasTypes.id_type == i.LAreas.id_type ) - .scalar_one() - ) + ).scalar_one() refs.append( { "area_name": i.LAreas.area_name, @@ -819,13 +815,16 @@ def __init__(self, id_area, id_doc_type, id_cors, remark): def __str__(self): return { - "commune": DB.session.execute(select(LAreas.area_name).where(LAreas.id_area == self.id_area)) - .scalar_one(), + "commune": DB.session.execute( + select(LAreas.area_name).where(LAreas.id_area == self.id_area) + ).scalar_one(), "type_doc": Utils.get_mnemo(self.id_doc_type), "type_classement": [ Utils.get_mnemo( DB.session.execute( - select(CorUrbanTypeRange.id_range_type).where(CorUrbanTypeRange.id_cor == id) + select(CorUrbanTypeRange.id_range_type).where( + CorUrbanTypeRange.id_cor == id + ) ).scalar_one() ) for id in self.id_cors diff --git a/backend/gn_module_zh/model/zh.py b/backend/gn_module_zh/model/zh.py index 57142a10..84c4a945 100644 --- a/backend/gn_module_zh/model/zh.py +++ b/backend/gn_module_zh/model/zh.py @@ -183,8 +183,7 @@ def get_protections(self): select(CorProtectionLevelType.id_protection_status).where( CorProtectionLevelType.id_protection == protec ) - ) - .scalar_one() + ).scalar_one() for protec in [ protection.id_protection for protection in ZH.get_data_by_id(CorZhProtection, self.zh.id_zh) diff --git a/backend/gn_module_zh/model/zh_schema.py b/backend/gn_module_zh/model/zh_schema.py index 629ee098..7c0a9fb4 100644 --- a/backend/gn_module_zh/model/zh_schema.py +++ b/backend/gn_module_zh/model/zh_schema.py @@ -267,10 +267,9 @@ def get_geofeature(self, recursif=True, relationships=()): @staticmethod def get_site_space_name(id): - return ( - DB.session.execute(select(BibSiteSpace.name).where(BibSiteSpace.id_site_space == id)) - .scalar_one() - ) + return DB.session.execute( + select(BibSiteSpace.name).where(BibSiteSpace.id_site_space == id) + ).scalar_one() @staticmethod def get_tzh_by_id(id): @@ -368,8 +367,7 @@ def get_id_types_ref_geo(id_zh, ref_geo_config): select(BibAreasTypes.id_type).where( BibAreasTypes.type_code == ref["type_code_ref_geo"] ) - ) - .scalar_one() + ).scalar_one() ) return ids @@ -634,7 +632,7 @@ def get_function_by_main_function(id_main): def get_mnemo_type(id_type): # methode utilisée ? if id_type: - test = 'test' + test = "test" return DB.session.execute( select(TNomenclatures).where(TNomenclatures.id_nomenclature == id_type) ).scalar_one() @@ -800,8 +798,7 @@ def get_range_by_doc(doc_id): select(TNomenclatures.mnemonique).where( TNomenclatures.id_nomenclature == range.id_range_type ) - ) - .scalar_one(), + ).scalar_one(), } ) return ranges diff --git a/backend/gn_module_zh/nomenclatures.py b/backend/gn_module_zh/nomenclatures.py index a030e060..f564b7fa 100644 --- a/backend/gn_module_zh/nomenclatures.py +++ b/backend/gn_module_zh/nomenclatures.py @@ -62,21 +62,16 @@ def get_corine_biotope(): def get_ch(lb_code): try: - CH_typo = ( - DB.session.execute(select(TypoRef.cd_typo).where(TypoRef.cd_table == "TYPO_CH")) - .scalar_one() - ) - CB_typo = ( - DB.session.execute(select(TypoRef.cd_typo).where(TypoRef.cd_table == "TYPO_CORINE_BIOTOPES")) - .scalar_one() - ) + CH_typo = DB.session.execute( + select(TypoRef.cd_typo).where(TypoRef.cd_table == "TYPO_CH") + ).scalar_one() + CB_typo = DB.session.execute( + select(TypoRef.cd_typo).where(TypoRef.cd_table == "TYPO_CORINE_BIOTOPES") + ).scalar_one() # get cd_hab_sortie list from lb_code of selected Corine Biotope - cd_hab_sortie = ( - DB.session.execute( - select(Habref.cd_hab).where(and_(Habref.lb_code == lb_code, Habref.cd_typo == CB_typo)) - ) - .scalar_one() - ) + cd_hab_sortie = DB.session.execute( + select(Habref.cd_hab).where(and_(Habref.lb_code == lb_code, Habref.cd_typo == CB_typo)) + ).scalar_one() # get all cd_hab_entre corresponding to cd_hab_sortie q_cd_hab_entre = DB.session.scalars( select(CorespHab).where( @@ -96,8 +91,10 @@ def get_ch(lb_code): "lb_code": hab.lb_code, "lb_hab_fr": hab.lb_hab_fr, "priority": DB.session.execute( - select(CorChStatus.priority).where(CorChStatus.lb_code == hab.lb_code).distinct() - ).scalar_one() + select(CorChStatus.priority) + .where(CorChStatus.lb_code == hab.lb_code) + .distinct() + ).scalar_one(), } ) return ch @@ -138,26 +135,20 @@ def get_impact_list(): def get_impact_category(impact): # get mnemonique of id_impact_type if impact.CorImpactTypes.id_impact_type is not None: - return ( - DB.session.execute( - select(TNomenclatures.mnemonique).where( - TNomenclatures.id_nomenclature == impact.CorImpactTypes.id_impact_type - ) + return DB.session.execute( + select(TNomenclatures.mnemonique).where( + TNomenclatures.id_nomenclature == impact.CorImpactTypes.id_impact_type ) - .scalar_one() - ) + ).scalar_one() return "Aucun" def get_function_list(mnemo): try: # get id_type of mnemo (ex : 'FONCTIONS_HYDRO') in BibNomenclatureTypes - id_type_main_function = ( - DB.session.execute( - select(BibNomenclaturesTypes.id_type).where(BibNomenclaturesTypes.mnemonique == mnemo) - ) - .scalar_one() - ) + id_type_main_function = DB.session.execute( + select(BibNomenclaturesTypes.id_type).where(BibNomenclaturesTypes.mnemonique == mnemo) + ).scalar_one() # get list of TNomenclatures ids by id_type nomenclature_ids = [ @@ -193,12 +184,9 @@ def get_function_list(mnemo): def get_all_function_list(mnemo): try: # get id_type of mnemo (ex : 'FONCTIONS_HYDRO') in BibNomenclatureTypes - id_type_main_function = ( - DB.session.execute( - select(BibNomenclaturesTypes.id_type).where(BibNomenclaturesTypes.mnemonique == mnemo) - ) - .scalar_one() - ) + id_type_main_function = DB.session.execute( + select(BibNomenclaturesTypes.id_type).where(BibNomenclaturesTypes.mnemonique == mnemo) + ).scalar_one() # get list of TNomenclatures ids by id_type nomenclature_ids = [ @@ -258,15 +246,13 @@ def get_protections(): select(TNomenclatures.mnemonique).where( TNomenclatures.id_nomenclature == protection.id_protection_status ) - ) - .scalar_one(), + ).scalar_one(), "id_protection_level": protection.id_protection_level, "mnemonique_level": DB.session.execute( select(TNomenclatures.mnemonique).where( TNomenclatures.id_nomenclature == protection.id_protection_level ) - ) - .scalar_one(), + ).scalar_one(), "category": get_protection_category(protection), "category_id": protection.id_protection_type, } @@ -284,14 +270,11 @@ def get_protections(): def get_protection_category(protection): if protection.id_protection_type is not None: - return ( - DB.session.execute( - select(TNomenclatures.mnemonique).where( - TNomenclatures.id_nomenclature == protection.id_protection_type - ) + return DB.session.execute( + select(TNomenclatures.mnemonique).where( + TNomenclatures.id_nomenclature == protection.id_protection_type ) - .scalar_one() - ) + ).scalar_one() return "Autre" diff --git a/backend/gn_module_zh/upload.py b/backend/gn_module_zh/upload.py index cc4095c5..41585bbb 100644 --- a/backend/gn_module_zh/upload.py +++ b/backend/gn_module_zh/upload.py @@ -113,7 +113,9 @@ def upload(request, extensions, pdf_size, jpg_size, upload_path, module_name, id return { "file_name": get_file_path(id_media).name, "full_path": str(get_file_path(id_media)), - "media_path": DB.session.execute(select(TMedias.media_path).where(TMedias.id_media == id_media)).scalar_one(), + "media_path": DB.session.execute( + select(TMedias.media_path).where(TMedias.id_media == id_media) + ).scalar_one(), "extension": get_extension(get_file_path(id_media).name), } diff --git a/backend/gn_module_zh/utils.py b/backend/gn_module_zh/utils.py index c6534b66..d0efb7fb 100644 --- a/backend/gn_module_zh/utils.py +++ b/backend/gn_module_zh/utils.py @@ -19,9 +19,9 @@ def get_main_picture_id(id_zh, media_list=None): media_list(list): media_list of the zh to set the main_pict_id if not present """ - main_pict_id = ( - DB.session.execute(select(TZH.main_pict_id).where(TZH.id_zh == id_zh)).scalar_one() - ) + main_pict_id = DB.session.execute( + select(TZH.main_pict_id).where(TZH.id_zh == id_zh) + ).scalar_one() if main_pict_id is None and media_list is not None and len(media_list) > 0: id_media = media_list[0].id_media stmt = update(TZH).where(TZH.id_zh == id_zh).values(main_pict_id=id_media) @@ -47,7 +47,7 @@ def get_last_pdf_export(id_zh, last_date) -> Query: TMedias.id_nomenclature_media_type == TNomenclatures.id_nomenclature, TNomenclatures.mnemonique == "PDF", TMedias.meta_update_date > last_date, - TMedias.title_fr.like(f"{id_zh}_fiche%.pdf") + TMedias.title_fr.like(f"{id_zh}_fiche%.pdf"), ) ) return DB.session.execute(query).first() @@ -93,14 +93,12 @@ def delete_file(id_media): def check_ref_geo_schema(): try: - id_type_com = ( - DB.session.execute(select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "DEP")) - .scalar_one() - ) - id_type_dep = ( - DB.session.execute(select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "DEP")) - .scalar_one() - ) + id_type_com = DB.session.execute( + select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "DEP") + ).scalar_one() + id_type_dep = DB.session.execute( + select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "DEP") + ).scalar_one() n_com = DB.session.scalar(select(func.count()).where(LAreas.id_type == id_type_com)) n_dep = DB.session.scalar(select(func.count()).where(LAreas.id_type == id_type_dep)) if n_com == 0 or n_dep == 0: From 0cd9291e6f89d43cfc872ecfcbd8e748d30f9182 Mon Sep 17 00:00:00 2001 From: Julien Corny Date: Thu, 18 Apr 2024 11:50:35 +0200 Subject: [PATCH 07/10] fix getattr error --- backend/gn_module_zh/hierarchy.py | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/backend/gn_module_zh/hierarchy.py b/backend/gn_module_zh/hierarchy.py index 73eeac80..1323abb9 100644 --- a/backend/gn_module_zh/hierarchy.py +++ b/backend/gn_module_zh/hierarchy.py @@ -109,18 +109,14 @@ def __get_cor_rule_id(self): DB.session.close() def __get_id_nomenc(self, id_type: int, cd_nomenc: str) -> int: - return getattr( - DB.session.scalars( - select(TNomenclatures).where( + return DB.session.scalars( + select(TNomenclatures.id_nomenclature).where( and_( TNomenclatures.id_type == id_type, TNomenclatures.cd_nomenclature == cd_nomenc, ) ) - ).first(), - "id_nomenclature", - None, - ) + ).first() def __get_nomencs(self, abb, cat=None): cat_id = self.__get_id_nomenc(self.__get_id_type("HIERARCHY"), cat) @@ -495,12 +491,9 @@ def __get_qualif_cat4_cat5(self): try: combination = self.__get_combination() # set qualif_id - qualif_id = getattr( - DB.session.scalars( - select(TCorQualif).where(TCorQualif.combination == combination) - ).first(), - "id_qualification", - ) + qualif_id = DB.session.scalars( + select(TCorQualif.id_qualification).where(TCorQualif.combination == combination) + ).first() return qualif_id except ZHApiError as e: raise ZHApiError( @@ -1206,9 +1199,10 @@ def get_denom(rb_id, col_name): rb_name = DB.session.execute( select(TRiverBasin.name).where(TRiverBasin.id_rb == rb_id) ).scalar_one() - return DB.session.execute( - select(RbNotesSummary.col_name).where(RbNotesSummary.bassin_versant == rb_name) - ).scalar_one() + return getattr( + DB.session.execute( + select(RbNotesSummary).where(RbNotesSummary.bassin_versant == rb_name) + ).scalar_one(), col_name) @staticmethod def get_str_note(note, denominator): From 03ab4c5a3a7a3849a844f633c0e1baa2878f9350 Mon Sep 17 00:00:00 2001 From: Etienne Delclaux Date: Tue, 21 May 2024 11:43:18 +0200 Subject: [PATCH 08/10] lint: adjust to last lint updates --- backend/gn_module_zh/blueprint.py | 8 ++------ backend/gn_module_zh/hierarchy.py | 26 ++++++++++++------------- backend/gn_module_zh/model/cards.py | 8 ++------ backend/gn_module_zh/model/zh_schema.py | 4 +--- 4 files changed, 18 insertions(+), 28 deletions(-) diff --git a/backend/gn_module_zh/blueprint.py b/backend/gn_module_zh/blueprint.py index b96a98a8..fb0b77c1 100644 --- a/backend/gn_module_zh/blueprint.py +++ b/backend/gn_module_zh/blueprint.py @@ -124,9 +124,7 @@ def get_zh(scope): def get_all_zh(info_role, query, limit, page, orderby=None, order="asc"): # try: # Pour obtenir le nombre de résultat de la requete sans le LIMIT - nb_results_without_limit = DB.session.scalar( - select(func.count()).select_from(query.subquery()) - ) + nb_results_without_limit = DB.session.scalar(select(func.count()).select_from(query.subquery())) user = info_role user_cruved = get_user_cruved() @@ -768,9 +766,7 @@ def deleteOneZh(id_zh): DB.session.execute(delete(CorZhRef).where(CorZhRef.id_zh == id_zh)) # delete criteres delim - id_lim_list = DB.session.execute( - select(TZH.id_lim_list).where(TZH.id_zh == id_zh) - ).scalar_one() + id_lim_list = DB.session.execute(select(TZH.id_lim_list).where(TZH.id_zh == id_zh)).scalar_one() DB.session.execute(delete(CorLimList).where(CorLimList.id_lim_list == id_lim_list)) # delete cor_zh_area diff --git a/backend/gn_module_zh/hierarchy.py b/backend/gn_module_zh/hierarchy.py index 1323abb9..d1a0de7a 100644 --- a/backend/gn_module_zh/hierarchy.py +++ b/backend/gn_module_zh/hierarchy.py @@ -110,13 +110,13 @@ def __get_cor_rule_id(self): def __get_id_nomenc(self, id_type: int, cd_nomenc: str) -> int: return DB.session.scalars( - select(TNomenclatures.id_nomenclature).where( - and_( - TNomenclatures.id_type == id_type, - TNomenclatures.cd_nomenclature == cd_nomenc, - ) + select(TNomenclatures.id_nomenclature).where( + and_( + TNomenclatures.id_type == id_type, + TNomenclatures.cd_nomenclature == cd_nomenc, ) - ).first() + ) + ).first() def __get_nomencs(self, abb, cat=None): cat_id = self.__get_id_nomenc(self.__get_id_type("HIERARCHY"), cat) @@ -492,8 +492,8 @@ def __get_qualif_cat4_cat5(self): combination = self.__get_combination() # set qualif_id qualif_id = DB.session.scalars( - select(TCorQualif.id_qualification).where(TCorQualif.combination == combination) - ).first() + select(TCorQualif.id_qualification).where(TCorQualif.combination == combination) + ).first() return qualif_id except ZHApiError as e: raise ZHApiError( @@ -870,9 +870,7 @@ def __get_rule_name(self): pass return ( DB.session.execute( - select(TRules, BibHierCategories) - .join(TRules) - .where(TRules.rule_id == self.rule_id) + select(TRules, BibHierCategories).join(TRules).where(TRules.rule_id == self.rule_id) ) .all()[0] .BibHierCategories.label.capitalize() @@ -1201,8 +1199,10 @@ def get_denom(rb_id, col_name): ).scalar_one() return getattr( DB.session.execute( - select(RbNotesSummary).where(RbNotesSummary.bassin_versant == rb_name) - ).scalar_one(), col_name) + select(RbNotesSummary).where(RbNotesSummary.bassin_versant == rb_name) + ).scalar_one(), + col_name, + ) @staticmethod def get_str_note(note, denominator): diff --git a/backend/gn_module_zh/model/cards.py b/backend/gn_module_zh/model/cards.py index 85ec29e2..1e4abd91 100644 --- a/backend/gn_module_zh/model/cards.py +++ b/backend/gn_module_zh/model/cards.py @@ -39,9 +39,7 @@ def get_mnemo(ids): ).scalar_one() return [ DB.session.execute( - select(TNomenclatures.label_default).where( - TNomenclatures.id_nomenclature == id - ) + select(TNomenclatures.label_default).where(TNomenclatures.id_nomenclature == id) ).scalar_one() for id in ids ] @@ -675,9 +673,7 @@ def other_ref_geo(self, ref_geo): for ref in CorZhArea.get_ref_geo_info(self.id_zh, id_types): for i in ref: type_code = DB.session.execute( - select(BibAreasTypes.type_code).where( - BibAreasTypes.id_type == i.LAreas.id_type - ) + select(BibAreasTypes.type_code).where(BibAreasTypes.id_type == i.LAreas.id_type) ).scalar_one() refs.append( { diff --git a/backend/gn_module_zh/model/zh_schema.py b/backend/gn_module_zh/model/zh_schema.py index 7c0a9fb4..ab2a8827 100644 --- a/backend/gn_module_zh/model/zh_schema.py +++ b/backend/gn_module_zh/model/zh_schema.py @@ -285,9 +285,7 @@ def get_zh_area_intersected(zh_area_type, id_zh_geom): ).all() if zh_area_type == "hydro_area": q = DB.session.scalars( - select(THydroArea).where( - THydroArea.geom.ST_Intersects(cast(id_zh_geom, Geography)) - ) + select(THydroArea).where(THydroArea.geom.ST_Intersects(cast(id_zh_geom, Geography))) ).all() if zh_area_type == "fct_area": q = DB.session.scalars( From d4f0864b52a48bdc0d6ea920e72caacd6765c6ae Mon Sep 17 00:00:00 2001 From: Etienne Delclaux Date: Mon, 27 May 2024 16:27:33 +0200 Subject: [PATCH 09/10] fix: adjust scalars and execute --- backend/gn_module_zh/blueprint.py | 22 ++++------ backend/gn_module_zh/model/cards.py | 52 +++++++++++------------- backend/gn_module_zh/model/code.py | 12 +++--- backend/gn_module_zh/model/zh_schema.py | 53 +++++++++++-------------- backend/gn_module_zh/nomenclatures.py | 46 ++++++++++----------- backend/gn_module_zh/search.py | 33 ++++++--------- backend/gn_module_zh/upload.py | 4 +- backend/gn_module_zh/utils.py | 15 ++++--- 8 files changed, 101 insertions(+), 136 deletions(-) diff --git a/backend/gn_module_zh/blueprint.py b/backend/gn_module_zh/blueprint.py index fb0b77c1..57b20e21 100644 --- a/backend/gn_module_zh/blueprint.py +++ b/backend/gn_module_zh/blueprint.py @@ -337,7 +337,7 @@ def get_pbf(): SELECT ST_AsGeobuf(q, 'geom') as pbf FROM (SELECT id_zh, geom from pr_zh.t_zh tz) AS q; """ - row = DB.session.execute(sql).first() + row = DB.session.execute(text(sql)).first() return Response(bytes(row["pbf"]) if row["pbf"] else bytes(), mimetype="application/protobuf") @@ -364,7 +364,7 @@ def get_pbf_complete(): 'bassin_versant', tz.bassin_versant) as json_arrays FROM pr_zh.atlas_app tz) AS q; """ - row = DB.session.execute(text(sql).limit(1)).first() + row = DB.session.execute(text(sql)).first() return Response(bytes(row["pbf"]) if row["pbf"] else bytes(), mimetype="application/protobuf") @@ -384,7 +384,7 @@ def get_json(): ) AS feature FROM (SELECT * FROM pr_zh.atlas_app tz) inputs) features; """ - row = DB.session.execute(text(sql).limit(1)).first() + row = DB.session.execute(text(sql)).first() return row["geojson"] @@ -457,7 +457,7 @@ def get_file_list(id_zh): """get a list of the zh files contained in static repo""" try: # FIXME: to optimize... See relationships and lazy join with sqlalchemy - zh_uuid = DB.session.execute(select(TZH.zh_uuid).where(TZH.id_zh == id_zh)).scalar_one() + zh_uuid = DB.session.scalar(select(TZH.zh_uuid).where(TZH.id_zh == id_zh)) q_medias = DB.session.execute( select(TMedias, TNomenclatures.label_default) .join( @@ -558,8 +558,7 @@ def get_all_photos(id_zh: int): TNomenclatures.id_nomenclature == TMedias.id_nomenclature_media_type, ) .order_by(TMedias.meta_update_date.desc()) - .where(TNomenclatures.label_default == "Photo") - .where(TZH.id_zh == id_zh) + .where(TNomenclatures.label_default == "Photo", TZH.id_zh == id_zh) ).all() api_uri = urljoin( f"{config['API_ENDPOINT']}/", @@ -799,7 +798,7 @@ def write_csv(id_zh): names = [] FILE_PATH = blueprint.config["file_path"] MODULE_NAME = blueprint.config["MODULE_CODE"].lower() - zh_code = DB.session.execute(select(TZH.code).where(TZH.id_zh == id_zh)).scalar_one() + zh_code = DB.session.scalar(select(TZH.code).where(TZH.id_zh == id_zh)) # author name user = DB.session.execute( select(User).where(User.id_role == g.current_user.id_role) @@ -959,11 +958,7 @@ def get_area_from_department() -> dict: @blueprint.route("/bassins", methods=["GET"]) @json_resp def bassins(): - query = ( - select(TRiverBasin) - .with_only_columns(TRiverBasin.id_rb, TRiverBasin.name) - .order_by(TRiverBasin.name) - ) + query = select(TRiverBasin.id_rb, TRiverBasin.name).order_by(TRiverBasin.name) resp = DB.session.execute(query).all() return [{"code": r.id_rb, "name": r.name} for r in resp] @@ -974,8 +969,7 @@ def get_hydro_zones_from_bassin() -> dict: code = request.json.get("code") if code: query = ( - select(THydroArea) - .with_only_columns(THydroArea.id_hydro, THydroArea.name, TRiverBasin.id_rb) + select(THydroArea.id_hydro, THydroArea.name, TRiverBasin.id_rb) .where(TRiverBasin.id_rb == code) .join( TRiverBasin, diff --git a/backend/gn_module_zh/model/cards.py b/backend/gn_module_zh/model/cards.py index 1e4abd91..795b5e19 100644 --- a/backend/gn_module_zh/model/cards.py +++ b/backend/gn_module_zh/model/cards.py @@ -32,15 +32,15 @@ class Utils(ZH): def get_mnemo(ids): if ids: if type(ids) is int: - return DB.session.execute( + return DB.session.scalar( select(TNomenclatures.label_default).where( TNomenclatures.id_nomenclature == ids ) - ).scalar_one() + ) return [ - DB.session.execute( + DB.session.scalar( select(TNomenclatures.label_default).where(TNomenclatures.id_nomenclature == id) - ).scalar_one() + ) for id in ids ] return [] @@ -495,23 +495,23 @@ def __str__(self): "hydros": self.hydro_zones, } + # TODO: replace in "where with multiples conditions" the coma by AND def __get_river_basins(self): return [ name - for (name,) in DB.session.execute( - select(TRiverBasin.name) - .where(TRiverBasin.id_rb == CorZhRb.id_rb) - .where(CorZhRb.id_zh == self.id_zh) + for name in DB.session.execute( + select(TRiverBasin.name).where( + TRiverBasin.id_rb == CorZhRb.id_rb, CorZhRb.id_zh == self.id_zh + ) ).all() ] def __get_hydro_zones(self): return [ name - for (name,) in DB.session.execute( + for name in DB.session.execute( select(THydroArea.name) - .where(THydroArea.id_hydro == CorZhHydro.id_hydro) - .where(CorZhHydro.id_zh == self.id_zh) + .where(THydroArea.id_hydro == CorZhHydro.id_hydro, CorZhHydro.id_zh == self.id_zh) .distinct() ).all() ] @@ -670,16 +670,14 @@ def instruments(self, instruments): def other_ref_geo(self, ref_geo): id_types = CorZhArea.get_id_types_ref_geo(self.id_zh, ref_geo) refs = [] - for ref in CorZhArea.get_ref_geo_info(self.id_zh, id_types): - for i in ref: - type_code = DB.session.execute( - select(BibAreasTypes.type_code).where(BibAreasTypes.id_type == i.LAreas.id_type) - ).scalar_one() + for ref_infos in CorZhArea.get_ref_geo_info(self.id_zh, id_types): + for info in ref_infos: + type_code = DB.session.get(BibAreasTypes, info.LAreas.id_type) refs.append( { - "area_name": i.LAreas.area_name, - "area_code": i.LAreas.area_code, - "url": i.LAreas.source, + "area_name": info.LAreas.area_name, + "area_code": info.LAreas.area_code, + "url": info.LAreas.source, "type_code": type_code, "zh_type_name": [ ref["zh_name"] @@ -770,9 +768,9 @@ def set_management(self, id_org, plans): def __str__(self): return { - "structure": DB.session.execute( + "structure": DB.session.scalar( select(BibOrganismes.name).where(BibOrganismes.id_org == self.id_org) - ).scalar_one(), + ), "plans": [plan.__str__() for plan in self.plans], } @@ -811,17 +809,15 @@ def __init__(self, id_area, id_doc_type, id_cors, remark): def __str__(self): return { - "commune": DB.session.execute( - select(LAreas.area_name).where(LAreas.id_area == self.id_area) - ).scalar_one(), + "commune": DB.session.get(LAreas, self.id_area), "type_doc": Utils.get_mnemo(self.id_doc_type), "type_classement": [ Utils.get_mnemo( - DB.session.execute( + DB.session.scalar( select(CorUrbanTypeRange.id_range_type).where( CorUrbanTypeRange.id_cor == id ) - ).scalar_one() + ) ) for id in self.id_cors ], @@ -1001,9 +997,7 @@ def __init__(self, id_action, id_priority_level, remark): def __str__(self): return { - "proposition": DB.session.execute( - select(BibActions.name).where(BibActions.id_action == self.id_action) - ).scalar_one(), + "proposition": DB.session.get(BibActions, self.id_action).name, "niveau": Utils.get_mnemo(self.id_priority_level), "remarque": Utils.get_string(self.remark), } diff --git a/backend/gn_module_zh/model/code.py b/backend/gn_module_zh/model/code.py index 3189f1d1..6cea6918 100644 --- a/backend/gn_module_zh/model/code.py +++ b/backend/gn_module_zh/model/code.py @@ -25,13 +25,11 @@ def get_departments(self): ).scalar_one() main_dep = None for dep in departments: - if ( - DB.session.scalar(select(dep.LAreas.geom.ST_Intersection(my_geom).ST_Area())) - > area - ): - area = DB.session.scalar( - select(dep.LAreas.geom.ST_Intersection(my_geom).ST_Area()) - ) + dep_area = DB.session.scalar( + select(dep.LAreas.geom.ST_Intersection(my_geom).ST_Area()) + ) + if dep_area > area: + area = dep_area main_dep = dep.LAreas.area_code if main_dep is None: raise ZHApiError(message="no_department", details="main_dep value is none") diff --git a/backend/gn_module_zh/model/zh_schema.py b/backend/gn_module_zh/model/zh_schema.py index ab2a8827..8953de87 100644 --- a/backend/gn_module_zh/model/zh_schema.py +++ b/backend/gn_module_zh/model/zh_schema.py @@ -267,13 +267,11 @@ def get_geofeature(self, recursif=True, relationships=()): @staticmethod def get_site_space_name(id): - return DB.session.execute( - select(BibSiteSpace.name).where(BibSiteSpace.id_site_space == id) - ).scalar_one() + return DB.session.scalar(select(BibSiteSpace.name).where(BibSiteSpace.id_site_space == id)) @staticmethod def get_tzh_by_id(id): - return DB.session.execute(select(TZH).where(TZH.id_zh == id)).scalar_one() + return DB.session.scalar(select(TZH).where(TZH.id_zh == id)) @staticmethod def get_zh_area_intersected(zh_area_type, id_zh_geom): @@ -308,10 +306,10 @@ def delims(self): def bassin_versant(self): bassin_versant = [ name - for (name,) in DB.session.execute( - select(TRiverBasin.name) - .where(TRiverBasin.id_rb == CorZhRb.id_rb) - .where(CorZhRb.id_zh == self.id_zh) + for name in DB.session.execute( + select(TRiverBasin.name).where( + TRiverBasin.id_rb == CorZhRb.id_rb, CorZhRb.id_zh == self.id_zh + ) ).all() ] return ", ".join([str(item) for item in bassin_versant]) @@ -361,11 +359,11 @@ def get_id_types_ref_geo(id_zh, ref_geo_config): for ref in ref_geo_config: if ref["active"]: ids.append( - DB.session.execute( + DB.session.scalar( select(BibAreasTypes.id_type).where( BibAreasTypes.type_code == ref["type_code_ref_geo"] ) - ).scalar_one() + ) ) return ids @@ -598,8 +596,7 @@ def get_functions(nomenc_ids): return DB.session.execute( select(CorMainFct, TNomenclatures) .join(TNomenclatures, TNomenclatures.id_nomenclature == CorMainFct.id_function) - .where(CorMainFct.active) - .where(CorMainFct.id_function.in_(nomenc_ids)) + .where(CorMainFct.active, CorMainFct.id_function.in_(nomenc_ids)) ).all() @staticmethod @@ -619,7 +616,7 @@ def get_main_function_list(ids): @staticmethod def get_function_by_main_function(id_main): - # méthode utilisée ? + # TODO: méthode utilisée ? return DB.session.execute( select(CorMainFct, TNomenclatures) .join(TNomenclatures, TNomenclatures.id_nomenclature == CorMainFct.id_function) @@ -628,12 +625,11 @@ def get_function_by_main_function(id_main): @staticmethod def get_mnemo_type(id_type): - # methode utilisée ? + # TODO: methode utilisée ? if id_type: - test = "test" - return DB.session.execute( + return DB.session.scalar( select(TNomenclatures).where(TNomenclatures.id_nomenclature == id_type) - ).scalar_one() + ) else: return "" @@ -666,13 +662,9 @@ class CorImpactList(DB.Model): @staticmethod def get_impacts_by_uuid(uuid_activity): - return ( - DB.session.execute( - select(CorImpactList).where(CorImpactList.id_impact_list == uuid_activity) - ) - .scalars() - .all() - ) + return DB.session.scalars( + select(CorImpactList).where(CorImpactList.id_impact_list == uuid_activity) + ).all() class TActivity(DB.Model): @@ -753,10 +745,11 @@ def get_functions_by_id_and_category(id_zh, category, is_eval=False): ] return DB.session.scalars( - select(TFunctions) - .where(TFunctions.id_zh == id_zh) - .where(TFunctions.id_function.in_(function_ids)) - .where(TFunctions.id_qualification.in_(qualif_ids)) + select(TFunctions).where( + TFunctions.id_zh == id_zh, + TFunctions.id_function.in_(function_ids), + TFunctions.id_qualification.in_(qualif_ids), + ) ).all() @@ -792,11 +785,11 @@ def get_range_by_doc(doc_id): { "id_cor": range.id_cor, "id_nomenclature": range.id_range_type, - "mnemonique": DB.session.execute( + "mnemonique": DB.session.scalar( select(TNomenclatures.mnemonique).where( TNomenclatures.id_nomenclature == range.id_range_type ) - ).scalar_one(), + ), } ) return ranges diff --git a/backend/gn_module_zh/nomenclatures.py b/backend/gn_module_zh/nomenclatures.py index f564b7fa..38f0491a 100644 --- a/backend/gn_module_zh/nomenclatures.py +++ b/backend/gn_module_zh/nomenclatures.py @@ -62,16 +62,14 @@ def get_corine_biotope(): def get_ch(lb_code): try: - CH_typo = DB.session.execute( - select(TypoRef.cd_typo).where(TypoRef.cd_table == "TYPO_CH") - ).scalar_one() - CB_typo = DB.session.execute( + CH_typo = DB.session.scalar(select(TypoRef.cd_typo).where(TypoRef.cd_table == "TYPO_CH")) + CB_typo = DB.session.scalar( select(TypoRef.cd_typo).where(TypoRef.cd_table == "TYPO_CORINE_BIOTOPES") - ).scalar_one() + ) # get cd_hab_sortie list from lb_code of selected Corine Biotope - cd_hab_sortie = DB.session.execute( + cd_hab_sortie = DB.session.scalar( select(Habref.cd_hab).where(and_(Habref.lb_code == lb_code, Habref.cd_typo == CB_typo)) - ).scalar_one() + ) # get all cd_hab_entre corresponding to cd_hab_sortie q_cd_hab_entre = DB.session.scalars( select(CorespHab).where( @@ -81,20 +79,18 @@ def get_ch(lb_code): # get list of cd_hab_entre/lb_code/lb_hab_fr for each cahier habitat ch = [] for q in q_cd_hab_entre: - hab = DB.session.execute( - select(Habref).where(Habref.cd_hab == q.cd_hab_entre) - ).scalar_one() + hab = DB.session.scalar(select(Habref).where(Habref.cd_hab == q.cd_hab_entre)) ch.append( { "cd_hab": q.cd_hab_entre, "front_name": hab.lb_code + " - " + hab.lb_hab_fr, "lb_code": hab.lb_code, "lb_hab_fr": hab.lb_hab_fr, - "priority": DB.session.execute( + "priority": DB.session.scalar( select(CorChStatus.priority) .where(CorChStatus.lb_code == hab.lb_code) .distinct() - ).scalar_one(), + ), } ) return ch @@ -135,20 +131,20 @@ def get_impact_list(): def get_impact_category(impact): # get mnemonique of id_impact_type if impact.CorImpactTypes.id_impact_type is not None: - return DB.session.execute( + return DB.session.scalar( select(TNomenclatures.mnemonique).where( TNomenclatures.id_nomenclature == impact.CorImpactTypes.id_impact_type ) - ).scalar_one() + ) return "Aucun" def get_function_list(mnemo): try: # get id_type of mnemo (ex : 'FONCTIONS_HYDRO') in BibNomenclatureTypes - id_type_main_function = DB.session.execute( + id_type_main_function = DB.session.scalar( select(BibNomenclaturesTypes.id_type).where(BibNomenclaturesTypes.mnemonique == mnemo) - ).scalar_one() + ) # get list of TNomenclatures ids by id_type nomenclature_ids = [ @@ -163,13 +159,11 @@ def get_function_list(mnemo): "id_nomenclature": function.CorMainFct.id_function, "mnemonique": function.TNomenclatures.mnemonique, "id_category": function.CorMainFct.id_main_function, - "category": DB.session.execute( + "category": DB.session.scalar( select(TNomenclatures.mnemonique).where( TNomenclatures.id_nomenclature == function.CorMainFct.id_main_function ) - ) - .scalar_one() - .upper(), + ).upper(), } for function in CorMainFct.get_functions(nomenclature_ids) ] @@ -242,17 +236,17 @@ def get_protections(): return [ { "id_protection_status": protection.id_protection_status, - "mnemonique_status": DB.session.execute( + "mnemonique_status": DB.session.scalar( select(TNomenclatures.mnemonique).where( TNomenclatures.id_nomenclature == protection.id_protection_status ) - ).scalar_one(), + ), "id_protection_level": protection.id_protection_level, - "mnemonique_level": DB.session.execute( + "mnemonique_level": DB.session.scalar( select(TNomenclatures.mnemonique).where( TNomenclatures.id_nomenclature == protection.id_protection_level ) - ).scalar_one(), + ), "category": get_protection_category(protection), "category_id": protection.id_protection_type, } @@ -270,11 +264,11 @@ def get_protections(): def get_protection_category(protection): if protection.id_protection_type is not None: - return DB.session.execute( + return DB.session.scalar( select(TNomenclatures.mnemonique).where( TNomenclatures.id_nomenclature == protection.id_protection_type ) - ).scalar_one() + ) return "Autre" diff --git a/backend/gn_module_zh/search.py b/backend/gn_module_zh/search.py index ee2a7b14..12d45ee9 100644 --- a/backend/gn_module_zh/search.py +++ b/backend/gn_module_zh/search.py @@ -160,11 +160,9 @@ def filter_area(query, json: dict, type_code: str): # Filter on departments subquery = ( - select(LAreas) - .with_only_columns(LAreas.area_name, LAreas.geom, LAreas.id_type, BibAreasTypes.type_code) + select(LAreas.area_name, LAreas.geom, LAreas.id_type, BibAreasTypes.type_code) .join(BibAreasTypes, LAreas.id_type == BibAreasTypes.id_type) - .where(BibAreasTypes.type_code == type_code) - .where(LAreas.area_code.in_(codes)) + .where(BibAreasTypes.type_code == type_code, LAreas.area_code.in_(codes)) .subquery() ) @@ -182,8 +180,7 @@ def filter_hydro(query, json): if codes and all(code is not None for code in codes): subquery = ( - select(THydroArea) - .with_only_columns(THydroArea.id_hydro, THydroArea.geom) + select(THydroArea.id_hydro, THydroArea.geom) .where(THydroArea.id_hydro.in_(codes)) .subquery() ) @@ -201,8 +198,7 @@ def filter_basin(query, json): if codes is not None: subquery = ( - select(TRiverBasin) - .with_only_columns( + select( TRiverBasin.id_rb, TRiverBasin.geom, ) @@ -234,8 +230,8 @@ def filter_fct(query, json: dict, type_: str): ids_conn = [f.get("id_nomenclature") for f in json.get("connaissances", [])] subquery = ( - select(TFunctions.id_zh) - .with_only_columns( + # TODO: be careful with this. To be verified + select( TFunctions.id_zh, TFunctions.id_function, TFunctions.id_qualification, @@ -267,10 +263,8 @@ def filter_statuts(query, json: dict): ids_statuts = [f.get("id_nomenclature") for f in json.get("statuts", [])] if ids_statuts: - subquery = ( - select(TOwnership.id_zh) - .with_only_columns(TOwnership.id_zh, TOwnership.id_status) - .where(TOwnership.id_status.in_(ids_statuts)) + subquery = select(TOwnership.id_zh, TOwnership.id_status).where( + TOwnership.id_status.in_(ids_statuts) ) query = query.where(TZH.id_zh == subquery.subquery().c.id_zh).distinct() @@ -282,8 +276,7 @@ def filter_plans(query, json: dict): if ids_plans and all(id_ is not None for id_ in ids_plans): subquery = ( - select(TManagementStructures.id_zh) - .with_only_columns( + select( TManagementPlans.id_nature, TManagementPlans.id_structure, TManagementStructures.id_structure, @@ -509,10 +502,10 @@ def generate_attributes_subquery(attributes: list): # TODO: see if all of these are usefull... Are cor_rule_id with note sufficient? subquery = ( - subquery.where(CorZhNotes.attribute_id.in_(attribute_ids)) - .where(CorZhNotes.note_type_id.in_(note_type_ids)) - .where(CorZhNotes.cor_rule_id.in_(cor_rule_ids)) - .where(CorZhNotes.note.in_(notes)) + subquery.where(CorZhNotes.attribute_id.in_(attribute_ids), + CorZhNotes.note_type_id.in_(note_type_ids), + CorZhNotes.cor_rule_id.in_(cor_rule_ids), + CorZhNotes.note.in_(notes)) ) return subquery.subquery() diff --git a/backend/gn_module_zh/upload.py b/backend/gn_module_zh/upload.py index 41585bbb..f9ab229a 100644 --- a/backend/gn_module_zh/upload.py +++ b/backend/gn_module_zh/upload.py @@ -113,9 +113,9 @@ def upload(request, extensions, pdf_size, jpg_size, upload_path, module_name, id return { "file_name": get_file_path(id_media).name, "full_path": str(get_file_path(id_media)), - "media_path": DB.session.execute( + "media_path": DB.session.scalar( select(TMedias.media_path).where(TMedias.id_media == id_media) - ).scalar_one(), + ), "extension": get_extension(get_file_path(id_media).name), } diff --git a/backend/gn_module_zh/utils.py b/backend/gn_module_zh/utils.py index d0efb7fb..7379bd4d 100644 --- a/backend/gn_module_zh/utils.py +++ b/backend/gn_module_zh/utils.py @@ -19,9 +19,7 @@ def get_main_picture_id(id_zh, media_list=None): media_list(list): media_list of the zh to set the main_pict_id if not present """ - main_pict_id = DB.session.execute( - select(TZH.main_pict_id).where(TZH.id_zh == id_zh) - ).scalar_one() + main_pict_id = DB.session.scalar(select(TZH.main_pict_id).where(TZH.id_zh == id_zh)) if main_pict_id is None and media_list is not None and len(media_list) > 0: id_media = media_list[0].id_media stmt = update(TZH).where(TZH.id_zh == id_zh).values(main_pict_id=id_media) @@ -38,6 +36,7 @@ def get_last_pdf_export(id_zh, last_date) -> Query: """ # TODO: Add with entities ? # Need to have do a separate query instead of reusing get_medias... + # TODO : compare efficiency with or without join query = ( select(TZH, TMedias, TNomenclatures) .with_only_columns(TMedias.id_media) @@ -93,12 +92,12 @@ def delete_file(id_media): def check_ref_geo_schema(): try: - id_type_com = DB.session.execute( - select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "DEP") - ).scalar_one() - id_type_dep = DB.session.execute( + id_type_com = DB.session.scalar( + select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "COM") + ) + id_type_dep = DB.session.scalar( select(BibAreasTypes.id_type).where(BibAreasTypes.type_code == "DEP") - ).scalar_one() + ) n_com = DB.session.scalar(select(func.count()).where(LAreas.id_type == id_type_com)) n_dep = DB.session.scalar(select(func.count()).where(LAreas.id_type == id_type_dep)) if n_com == 0 or n_dep == 0: From ed71d7c93da7ef2e9c78eb924374f1bef724a0c4 Mon Sep 17 00:00:00 2001 From: Etienne Delclaux Date: Mon, 27 May 2024 16:55:19 +0200 Subject: [PATCH 10/10] fix: update geometry --- backend/gn_module_zh/geometry.py | 45 +++++++++++++++----------------- backend/gn_module_zh/search.py | 6 ++--- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/backend/gn_module_zh/geometry.py b/backend/gn_module_zh/geometry.py index cc2d748e..b8c92d1c 100644 --- a/backend/gn_module_zh/geometry.py +++ b/backend/gn_module_zh/geometry.py @@ -2,6 +2,7 @@ from geoalchemy2.shape import to_shape from geonature.utils.env import DB +from sqlalchemy import func from sqlalchemy.sql import select, func from werkzeug.exceptions import BadRequest @@ -15,11 +16,7 @@ def set_geom(geometry, id_zh=None): if not id_zh: id_zh = 0 # SetSRID for POSTGIS < 3.0 compat - # select only already existing ZH geometries which intersect with the new ZH geometry - # polygon = DB.session.execute( - # select(func.ST_SetSRID(func.ST_GeomFromGeoJSON(str(geometry)), 4326)) - # ).scalar_one() q_zh = DB.session.scalars( select(TZH) .where( @@ -28,7 +25,8 @@ def set_geom(geometry, id_zh=None): func.ST_GeogFromWKB(func.ST_AsEWKB(str(geometry))), ) ) - .where(func.ST_Touches( + .where( + func.ST_Touches( func.ST_GeomFromWKB(func.ST_AsEWKB(TZH.geom), 4326), func.ST_GeomFromWKB(func.ST_AsEWKB(str(geometry)), 4326), ) @@ -36,8 +34,10 @@ def set_geom(geometry, id_zh=None): ) ).all() - is_intersected = False + polygon = DB.session.scalar( + select(func.ST_SetSRID(func.ST_GeomFromGeoJSON(str(geometry)), 4326)) + ) for zh in q_zh: if zh.id_zh != id_zh: zh_geom = DB.session.scalar(select(func.ST_GeogFromWKB(func.ST_AsEWKB(zh.geom)))) @@ -46,18 +46,19 @@ def set_geom(geometry, id_zh=None): ) if DB.session.scalar(select(func.ST_Intersects(polygon_geom, zh_geom))): if DB.session.scalar( - func.ST_GeometryType(func.ST_Intersection(zh_geom, polygon_geom, 0.1)) - ) not in ["ST_LineString", "ST_MultiLineString"]: + select(func.ST_GeometryType(func.ST_Intersection(zh_geom, polygon_geom, 0.1))) + ) not in ["ST_LineString", "ST_MultiLineString"]: is_intersected = True if DB.session.scalar( - func.ST_Contains( - zh_geom, - polygon_geom, - + select( + func.ST_Contains( + zh_geom, + polygon_geom, + ) ) ): raise BadRequest("La ZH est entièrement dans une ZH existante") - # TODO: not detected if contained entirely in 2 or more ZH polygons + # TODO: not detected if contained entirely in 2 or more ZH polygons polygon = DB.session.scalar(select(func.ST_Difference(polygon_geom, zh_geom))) return {"polygon": polygon, "is_intersected": is_intersected} @@ -79,20 +80,16 @@ def get_main_rb(query: list) -> int: rb_id = None area = 0 for q_ in query: - zh_polygon = ( - DB.session.execute(select(TZH.geom).where(TZH.id_zh == getattr(q_, "id_zh"))) - .first() - .geom + zh_polygon = DB.session.execute( + select(TZH.geom).where(TZH.id_zh == getattr(q_, "id_zh")).first() ) - rb_polygon = ( - DB.session.execute( - select(CorZhRb, TRiverBasin) - .join(TRiverBasin, TRiverBasin.id_rb == CorZhRb.id_rb) - .where(TRiverBasin.id_rb == getattr(q_, "id_rb")) - ) + rb_polygon = DB.session.execute( + select(TRiverBasin.geom) + .join(TRiverBasin, TRiverBasin.id_rb == CorZhRb.id_rb) + .where(TRiverBasin.id_rb == getattr(q_, "id_rb")) .first() - .TRiverBasin.geom ) + intersection = DB.session.scalar( select( func.ST_Intersection( diff --git a/backend/gn_module_zh/search.py b/backend/gn_module_zh/search.py index 12d45ee9..c686c7eb 100644 --- a/backend/gn_module_zh/search.py +++ b/backend/gn_module_zh/search.py @@ -501,11 +501,11 @@ def generate_attributes_subquery(attributes: list): notes.append(attribute["note"]) # TODO: see if all of these are usefull... Are cor_rule_id with note sufficient? - subquery = ( - subquery.where(CorZhNotes.attribute_id.in_(attribute_ids), + subquery = subquery.where( + CorZhNotes.attribute_id.in_(attribute_ids), CorZhNotes.note_type_id.in_(note_type_ids), CorZhNotes.cor_rule_id.in_(cor_rule_ids), - CorZhNotes.note.in_(notes)) + CorZhNotes.note.in_(notes), ) return subquery.subquery()