Skip to content

Commit

Permalink
sqla 1.4
Browse files Browse the repository at this point in the history
  • Loading branch information
joelclems committed Jan 14, 2024
1 parent d555327 commit 5026732
Show file tree
Hide file tree
Showing 20 changed files with 125 additions and 86 deletions.
4 changes: 2 additions & 2 deletions backend/gn_modulator/module/breadcrumbs.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def breadcrumbs(cls, module_code, page_code, data):
q = sm.get_row(
data[sm.Model().pk_field_name()], module_code=module_code, params={}
)
m = q.one()
m = db.session.execute(q).scalar_one()
data_label = sm.serialize(m, fields=[sm.label_field_name()])
# label_page = f"{sm.label()} {data_label[sm.label_field_name()]}"
label_page = f"{sm.label()} {getAttr(data_label, sm.label_field_name())}"
Expand All @@ -63,7 +63,7 @@ def breadcrumbs(cls, module_code, page_code, data):
if ":" in parent_page_url and data.get(sm.Model().pk_field_name()):
data_parent_key = parent_page_url.split(":")[1]
q = sm.get_row(data[sm.Model().pk_field_name()], params={})
m = q.one()
m = db.session.execute(q).scalar_one()

Check warning on line 66 in backend/gn_modulator/module/breadcrumbs.py

View check run for this annotation

Codecov / codecov/patch

backend/gn_modulator/module/breadcrumbs.py#L66

Added line #L66 was not covered by tests

data_parent = sm.serialize(m, fields=[data_parent_key])
else:
Expand Down
56 changes: 27 additions & 29 deletions backend/gn_modulator/query/existing_permission.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,39 +58,37 @@ def synthese_subquery_scope(cls, id_role):
scope_expression = db.session.query(Synthese).with_entities(
Synthese.id_synthese,
sa.case(
[
(
sa.or_(
Synthese.id_digitiser == id_role,
sa.exists().where(
sa.and_(
pre_scope.c.id_synthese == Synthese.id_synthese,
sa.or_(
pre_scope.c.id_role_obs == pre_scope.c.id_role_cur,
pre_scope.c.id_role_jdd == pre_scope.c.id_role_cur,
pre_scope.c.id_role_af == pre_scope.c.id_role_cur,
),
)
),
(
sa.or_(
Synthese.id_digitiser == id_role,
sa.exists().where(
sa.and_(
pre_scope.c.id_synthese == Synthese.id_synthese,
sa.or_(
pre_scope.c.id_role_obs == pre_scope.c.id_role_cur,
pre_scope.c.id_role_jdd == pre_scope.c.id_role_cur,
pre_scope.c.id_role_af == pre_scope.c.id_role_cur,
),
)
),
1,
),
(
sa.or_(
sa.exists().where(
sa.and_(
pre_scope.c.id_synthese == Synthese.id_synthese,
sa.or_(
pre_scope.c.id_organisme_obs == pre_scope.c.id_organisme_cur,
pre_scope.c.id_organisme_jdd == pre_scope.c.id_organisme_cur,
pre_scope.c.id_organisme_af == pre_scope.c.id_organisme_cur,
),
)
),
1,
),
(
sa.or_(
sa.exists().where(
sa.and_(
pre_scope.c.id_synthese == Synthese.id_synthese,
sa.or_(
pre_scope.c.id_organisme_obs == pre_scope.c.id_organisme_cur,
pre_scope.c.id_organisme_jdd == pre_scope.c.id_organisme_cur,
pre_scope.c.id_organisme_af == pre_scope.c.id_organisme_cur,
),
)
),
2,
),
],
2,
),
else_=3,
).label("scope"),
)
Expand Down
2 changes: 1 addition & 1 deletion backend/gn_modulator/query/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def process_filters(Model, query, filters):
filters_processed, query = process_filter_array(Model, query, filters)

if filters_processed is not None:
query = query.filter(filters_processed)
query = query.where(filters_processed)

return query

Expand Down
3 changes: 2 additions & 1 deletion backend/gn_modulator/query/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ def query_list(Model, module_code, action, params, query_type, id_role=None):
TODO ajout permission_object_code ??
"""
query = Model.query

query = sa.select(Model)

model_pk_fields = [getattr(Model, pk_field_name) for pk_field_name in Model.pk_field_names()]

Expand Down
2 changes: 1 addition & 1 deletion backend/gn_modulator/query/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@


def pretty_sql(query):
txt = str(query.statement.compile(compile_kwargs={"literal_binds": True}))
txt = str(query.compile(compile_kwargs={"literal_binds": True}))
txt = txt.replace("%%", "%")
txt = sqlparse.format(txt, reindent=True, keywordcase="upper")
return txt
Expand Down
11 changes: 7 additions & 4 deletions backend/gn_modulator/routes/utils/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def get_list_rest(module_code, object_code, additional_params={}):
response.mimetype = "text/plain"
return response

res_list = [] if params.get("only_info") else q_list.all()
res_list = [] if params.get("only_info") else db.session.execute(q_list).all()

out = {
**query_infos,
Expand Down Expand Up @@ -84,7 +84,7 @@ def get_one_rest(module_code, object_code, value):
params=params,
)

m = q.one()
m = db.session.execute(q).unique().one()
except sm.errors.SchemaUnsufficientCruvedRigth as e:
return f"Erreur Cruved : {str(e)}", 403

Expand Down Expand Up @@ -154,13 +154,16 @@ def delete_rest(module_code, object_code, value):

params = parse_request_args(object_definition)

dict_out = sm.get_row_as_dict(
q = sm.get_row(
value,
field_name=params.get("field_name"),
module_code=permission_module_code,
action="D",
fields=params.get("fields"),
params=params,
)
m = db.session.execute(q).scalar_one()

dict_out = sm.serialize(m, fields=params.get("fields"), as_geojson=params.get("as_geojson"))

try:
sm.delete_row(
Expand Down
13 changes: 8 additions & 5 deletions backend/gn_modulator/schema/doc.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import yaml
from geonature.utils.env import db
from gn_modulator.utils.yaml import YmlLoader
from gn_modulator.query.repository import query_list

Expand Down Expand Up @@ -99,17 +99,20 @@ def doc_nomenclature_values(self, key):
nomenclature_type = property_def["nomenclature_type"]
txt += " - *valeurs* :\n"
sm_nom = self.cls("ref_nom.nomenclature")
res = query_list(

fields = ["label_fr", "cd_nomenclature"]
q = query_list(
sm_nom.Model(),
"MODULATOR",
"R",
{
"fields": ["label_fr", "cd_nomenclature"],
"fields": fields,
"filters": [f"nomenclature_type.mnemonique = {nomenclature_type}"],
},
"select",
).all()
values = sm_nom.serialize_list(res, ["label_fr", "cd_nomenclature"])
)
m_list = db.session.execute(q)
values = sm_nom.serialize_list(m_list, fields)

for v in values:
txt += f" - **{v['cd_nomenclature']}** *{v['label_fr']}*\n"
Expand Down
3 changes: 2 additions & 1 deletion backend/gn_modulator/schema/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import csv
import datetime
from gn_modulator.query.utils import pretty_sql
from geonature.utils.env import db


class Line(object):
Expand Down Expand Up @@ -227,7 +228,7 @@ def process_export_csv(self, module_code, query_list, params):
params.get("fields"), params.get("process_field_name")
)

res_list = self.serialize_list(q.all(), fields=fields)
res_list = self.serialize_list(db.session.execute(q).unique().all(), fields=fields)

if not res_list:
return jsonify([]), 404
Expand Down
6 changes: 4 additions & 2 deletions backend/gn_modulator/schema/features/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from sqlalchemy.orm.exc import NoResultFound
from .. import errors
from gn_modulator.utils.cache import get_global_cache, clear_global_cache, set_global_cache
from geonature.utils.env import db


class SchemaBaseFeatures:
Expand Down Expand Up @@ -77,11 +78,12 @@ def get_foreign_key(self, key_process, rel_test_values, process_one=False):
return None

try:
m = sm_rel.get_row(
q = sm_rel.get_row(
rel_test_values,
rel_test_keys,
params={}, # sinon bug et utilise un param précédent ????
).one()
)
m = db.session.execute(q).scalar_one()
pk = getattr(m, sm_rel.Model().pk_field_name())
set_global_cache(["import_pk_keys", self.schema_code(), cache_key], pk)
return pk
Expand Down
3 changes: 3 additions & 0 deletions backend/gn_modulator/schema/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ def process_relation_model(self, key, relationship_def, Model):

kwargs = {}

if relationship_def.get("overlaps"):
kwargs["overlaps"] = relationship_def["overlaps"]

if relationship_def.get("relation_type") == "1-1":
kwargs["uselist"] = False

Expand Down
2 changes: 1 addition & 1 deletion backend/gn_modulator/schema/models/column_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def cp_select(self, key, column_property_def):
index += 1
cp = func.concat(*items)
if conditions:
cp = select([cp]).where(and_(*conditions))
cp = select(cp).where(and_(*conditions))
return cp

raise errors.SchemaModelColumnPropertyError(
Expand Down
41 changes: 32 additions & 9 deletions backend/gn_modulator/schema/repositories.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ def update_row(
query_type="update",
)

m = q.one()
m = db.session.execute(q).unique().scalar_one()

if not self.is_new_data(m, data):
return m, False

Expand Down Expand Up @@ -221,13 +222,31 @@ def delete_row(
action="D",
params=params,
query_type="delete",
).cte("pre_delete")

Model = self.Model()
table = Model.__table__
q_delete = sa.delete(table).where(
sa.and_(
*map(
lambda x: getattr(table.c, x) == getattr(subquery_delete.c, x),
Model.pk_field_names(),
)
)
)

# patch pourris pourquoi sql ne met pas USING PDBDMSRMLGP???
propper_sql_delete = str(q_delete.compile(compile_kwargs={"literal_binds": True})).replace(
", pre_delete", "USING pre_delete"
)

db.session.execute(
sa.text(propper_sql_delete), execution_options={"synchronize_session": False}
)
# https://stackoverflow.com/questions/49794899/flask-sqlalchemy-delete-query-failing-with-could-not-evaluate-current-criteria?noredirect=1&lq=1
if not multiple:
subquery_delete.one()
subquery_delete.delete(synchronize_session=False)
db.session.flush()
# db.session.execute(q)
# m.delete(synchronize_session=False)
# db.session.flush()

if commit:
db.session.commit()
Expand All @@ -240,8 +259,10 @@ def get_query_infos(self, module_code=MODULE_CODE, action="R", params={}, url=No
action=action,
params=params,
query_type="total",
)
count_total = subquery_count_total.count()
).cte("count_total")
count_total = db.session.execute(
sa.select(sa.func.count()).select_from(subquery_count_total)
).scalar_one()

if params.get("filters"):
subquery_count_filtered = query_list(
Expand All @@ -250,9 +271,11 @@ def get_query_infos(self, module_code=MODULE_CODE, action="R", params={}, url=No
action=action,
params=params,
query_type="filtered",
)
).cte("count_filtered")

count_filtered = subquery_count_filtered.count()
count_filtered = db.session.execute(

Check warning on line 276 in backend/gn_modulator/schema/repositories.py

View check run for this annotation

Codecov / codecov/patch

backend/gn_modulator/schema/repositories.py#L276

Added line #L276 was not covered by tests
sa.select(sa.func.count()).select_from(subquery_count_filtered)
).scalar_one()
else:
count_filtered = count_total

Expand Down
4 changes: 2 additions & 2 deletions backend/gn_modulator/schema/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ def serialize(self, m, fields=None, as_geojson=False, geometry_field_name=None):
return data

def is_res_multiple_columns(self, m):
return isinstance(m, tuple)
return isinstance(m, sa.engine.row.Row)

def get_res_model(self, m):
return m[0] if self.is_res_multiple_columns(m) else m
Expand Down Expand Up @@ -365,7 +365,7 @@ def get_row_as_dict(
params={"fields": fields},
query_type=query_type,
)
m = q.one()
m = db.session.execute(q).one()

except sa.orm.exc.NoResultFound:
return None
Expand Down
2 changes: 1 addition & 1 deletion backend/gn_modulator/schematisable.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def sql_type(cls, key):
sql_type = "VARCHAR"
if sql_type == "DATETIME":
sql_type = "TIMESTAMP"
if "GEOMETRY" in sql_type:
if "GEOMETRY" in sql_type.upper():
sql_type = "GEOMETRY"

return sql_type
Expand Down
4 changes: 3 additions & 1 deletion backend/gn_modulator/tests/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ def passages_faune_with_diagnostic(users):
uuids = ["0c92af92-000b-401c-9994-f2c12470493a", "0c92af92-000b-401c-9994-f2c12470493b"]
passages_faune = []

organisme = Organisme.query.filter_by(nom_organisme="ALL").one()
organisme = db.session.execute(
sa.select(Organisme).filter_by(nom_organisme="ALL")
).scalar_one()

with db.session.begin_nested():
for uuid in uuids:
Expand Down
2 changes: 1 addition & 1 deletion backend/gn_modulator/tests/test_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ def test_schematisable(self):
{"fields": ["id_passage_faune", "nomenclatures_ouvrage_type.label_fr"]},
"select",
)
res = q.all()
res = db.session.execute(q).unique()
sm.serialize_list(res, fields=["nomenclatures_ouvrage_type.label_fr"])
Loading

0 comments on commit 5026732

Please sign in to comment.