territories-dashboard-lib 0.1.39b2__py3-none-any.whl → 1.1.1.dev10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of territories-dashboard-lib might be problematic. Click here for more details.
- territories_dashboard_lib/geo_lib/admin.py +2 -0
- territories_dashboard_lib/geo_lib/migrations/0003_geofeature_color_column_geofeature_size_column.py +23 -0
- territories_dashboard_lib/geo_lib/models.py +12 -0
- territories_dashboard_lib/geo_lib/payloads.py +7 -21
- territories_dashboard_lib/geo_lib/views.py +58 -53
- territories_dashboard_lib/indicators_lib/enums.py +61 -37
- territories_dashboard_lib/indicators_lib/migrations/0004_alter_indicator_min_mesh.py +18 -0
- territories_dashboard_lib/indicators_lib/migrations/0005_auto_20251203_1621.py +2 -2
- territories_dashboard_lib/indicators_lib/models.py +9 -6
- territories_dashboard_lib/indicators_lib/payloads.py +14 -1
- territories_dashboard_lib/indicators_lib/query/commons.py +90 -104
- territories_dashboard_lib/indicators_lib/query/comparison.py +8 -3
- territories_dashboard_lib/indicators_lib/query/details.py +8 -13
- territories_dashboard_lib/indicators_lib/query/histogram.py +0 -1
- territories_dashboard_lib/indicators_lib/query/indicator_card.py +12 -7
- territories_dashboard_lib/indicators_lib/query/top_10.py +12 -12
- territories_dashboard_lib/indicators_lib/query/utils.py +9 -0
- territories_dashboard_lib/indicators_lib/table.py +15 -12
- territories_dashboard_lib/indicators_lib/views.py +49 -59
- territories_dashboard_lib/superset_lib/logic.py +24 -25
- territories_dashboard_lib/superset_lib/migrations/0002_alter_filter_mesh.py +18 -0
- territories_dashboard_lib/tracking_lib/enums.py +2 -0
- territories_dashboard_lib/tracking_lib/migrations/0005_alter_page_cmp_territory_mesh_alter_page_submesh_and_more.py +28 -0
- territories_dashboard_lib/tracking_lib/migrations/0006_alter_event_name.py +18 -0
- territories_dashboard_lib/tracking_lib/payloads.py +4 -2
- territories_dashboard_lib/tracking_lib/views.py +7 -6
- territories_dashboard_lib/website_lib/conf.py +14 -0
- territories_dashboard_lib/website_lib/context_processors.py +2 -1
- territories_dashboard_lib/website_lib/migrations/0005_mainconf_meshes.py +20 -0
- territories_dashboard_lib/website_lib/models.py +12 -0
- territories_dashboard_lib/website_lib/params.py +34 -22
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/anchor.mjs +43 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/comparaison/page.mjs +7 -9
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/page.mjs +2 -7
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/dom.mjs +0 -15
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/enums.mjs +13 -10
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/side_panel.mjs +1 -15
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/theme/page.mjs +7 -9
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/track-visible-indicators.mjs +121 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/react/indicatorMap.bundle.js +2 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/react/sankeyGraph.bundle.js +2 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/react/vendors.bundle.js +2 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/layout/base.css +12 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/comparaison/[theme]/page.html +4 -3
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/anchor.html +14 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/geo_params.html +3 -3
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/indicator-card.html +14 -8
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/select_territory.html +32 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_geo.html +8 -35
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/details/components/histogram.html +1 -1
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/details/page.html +9 -8
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/methodo/methodo.js +28 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/methodo/page.html +40 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/themes/page.html +4 -5
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/sitemap/page.html +9 -0
- territories_dashboard_lib/website_lib/templatetags/other_filters.py +6 -3
- territories_dashboard_lib/website_lib/views.py +100 -0
- {territories_dashboard_lib-0.1.39b2.dist-info → territories_dashboard_lib-1.1.1.dev10.dist-info}/METADATA +2 -2
- {territories_dashboard_lib-0.1.39b2.dist-info → territories_dashboard_lib-1.1.1.dev10.dist-info}/RECORD +62 -51
- territories_dashboard_lib/indicators_lib/migrations/0006_alter_theme_action_theme_alter_theme_objectif_theme.py +0 -23
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_methodo.css +0 -29
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_methodo.html +0 -45
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_methodo.js +0 -19
- {territories_dashboard_lib-0.1.39b2.dist-info → territories_dashboard_lib-1.1.1.dev10.dist-info}/WHEEL +0 -0
- {territories_dashboard_lib-0.1.39b2.dist-info → territories_dashboard_lib-1.1.1.dev10.dist-info}/licenses/licence.md +0 -0
- {territories_dashboard_lib-0.1.39b2.dist-info → territories_dashboard_lib-1.1.1.dev10.dist-info}/top_level.txt +0 -0
|
@@ -1,9 +1,55 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
)
|
|
1
|
+
from territories_dashboard_lib.indicators_lib.payloads import Territory
|
|
2
|
+
|
|
3
|
+
from ..enums import FRANCE_DB_VALUES, MeshLevel
|
|
5
4
|
from ..models import AggregationFunctions, Indicator
|
|
6
|
-
from .utils import get_breakdown_dimension, run_custom_query
|
|
5
|
+
from .utils import format_sql_codes, get_breakdown_dimension, run_custom_query
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_mesh_column_name(mesh: MeshLevel):
|
|
9
|
+
return f"code_{mesh}"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def get_sub_territories(
|
|
13
|
+
*,
|
|
14
|
+
submesh: MeshLevel,
|
|
15
|
+
territory: Territory = None,
|
|
16
|
+
with_center=False,
|
|
17
|
+
codes: list[str] = None,
|
|
18
|
+
):
|
|
19
|
+
"""
|
|
20
|
+
Récupère une liste des territoires appartenant à un territoire parent.
|
|
21
|
+
params:
|
|
22
|
+
submesh: maille des sous-territoires à récupérer
|
|
23
|
+
territory: territoire parent des sous-territoires
|
|
24
|
+
with_center: si True, ajoute le centre de chaque territoire
|
|
25
|
+
codes: codes des sous-territoires à récupérer, peut-être utilisé en absence du territoire parent
|
|
26
|
+
"""
|
|
27
|
+
parent_mesh_join = ""
|
|
28
|
+
condition = ""
|
|
29
|
+
if territory is None and codes:
|
|
30
|
+
condition = f"WHERE arbo.code IN {format_sql_codes(codes)}"
|
|
31
|
+
elif territory and submesh == territory.mesh:
|
|
32
|
+
condition = f"WHERE arbo.code IN {territory.sql_codes}"
|
|
33
|
+
elif territory:
|
|
34
|
+
parent_mesh_join = f"JOIN arbo_{territory.mesh}_{submesh} AS j ON j.{submesh}=arbo.code AND j.{territory.mesh} IN {territory.sql_codes}"
|
|
35
|
+
|
|
36
|
+
center = ""
|
|
37
|
+
contours_join = ""
|
|
38
|
+
if with_center:
|
|
39
|
+
center = ", ST_ASGEOJSON(ST_CENTROID(contours.geometry)) as center"
|
|
40
|
+
contours_join = f"JOIN contours_simplified_{submesh} as contours ON arbo.code = contours.code"
|
|
41
|
+
|
|
42
|
+
query = f"""
|
|
43
|
+
SELECT DISTINCT
|
|
44
|
+
arbo.code,
|
|
45
|
+
arbo.name
|
|
46
|
+
{center}
|
|
47
|
+
FROM arbo_{submesh} AS arbo
|
|
48
|
+
{parent_mesh_join}
|
|
49
|
+
{contours_join}
|
|
50
|
+
{condition}
|
|
51
|
+
"""
|
|
52
|
+
return run_custom_query(query)
|
|
7
53
|
|
|
8
54
|
|
|
9
55
|
def get_last_year(indicator, mesh):
|
|
@@ -18,9 +64,9 @@ def generate_aggregate_query(indicator, territory, submesh, filters, slicer):
|
|
|
18
64
|
aggregat AS
|
|
19
65
|
(
|
|
20
66
|
SELECT
|
|
21
|
-
{calculate_aggregate_values(indicator)}, {slicer}
|
|
67
|
+
{calculate_aggregate_values(indicator)}, indic.{slicer}
|
|
22
68
|
FROM
|
|
23
|
-
{
|
|
69
|
+
{get_values_for_indicator_territory_submesh(indicator=indicator, territory=territory, submesh=submesh)}
|
|
24
70
|
{add_optional_filters(indicator, filters)}
|
|
25
71
|
AND annee = (SELECT * FROM annee_max)
|
|
26
72
|
GROUP BY (indic.{slicer})
|
|
@@ -30,9 +76,8 @@ def generate_aggregate_query(indicator, territory, submesh, filters, slicer):
|
|
|
30
76
|
|
|
31
77
|
|
|
32
78
|
def generate_aggregate_query_for_location(indicator, territory, submesh, filters):
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
)
|
|
79
|
+
mesh_col = get_mesh_column_name(submesh)
|
|
80
|
+
return generate_aggregate_query(indicator, territory, submesh, filters, mesh_col)
|
|
36
81
|
|
|
37
82
|
|
|
38
83
|
def add_optional_filters(indicator: Indicator, filters):
|
|
@@ -47,75 +92,48 @@ def add_optional_filters(indicator: Indicator, filters):
|
|
|
47
92
|
return condition
|
|
48
93
|
|
|
49
94
|
|
|
50
|
-
def
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
(SELECT distinct("NOM_{mapped_submesh}") as territory_1, "{mapped_submesh}" as territory_1_id, "{mapped_submesh}" from arborescence_geo) arbo1
|
|
57
|
-
on arbo1."{mapped_submesh}" = indic.code_{submesh.lower()}_1
|
|
58
|
-
JOIN
|
|
59
|
-
(SELECT distinct("NOM_{mapped_submesh}") as territory_2, "{mapped_submesh}" as territory_2_id, "{mapped_submesh}" from arborescence_geo) arbo2
|
|
60
|
-
on arbo2."{mapped_submesh}" = indic.code_{submesh.lower()}_2
|
|
61
|
-
"""
|
|
62
|
-
else:
|
|
63
|
-
join_clause = f"""
|
|
64
|
-
JOIN
|
|
65
|
-
(SELECT distinct("NOM_{mapped_submesh}") as lieu, "{mapped_submesh}" as territoryid, "{mapped_submesh}" from arborescence_geo) arbo
|
|
66
|
-
on arbo."{mapped_submesh}" = indic.code_{submesh.lower()}
|
|
67
|
-
"""
|
|
68
|
-
return join_clause
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
def get_table_data_for_geography(
|
|
72
|
-
indicator,
|
|
73
|
-
territory,
|
|
74
|
-
submesh=MeshLevel.Region,
|
|
75
|
-
include_place_names=None,
|
|
76
|
-
flows=False,
|
|
95
|
+
def get_values_for_indicator_territory_submesh(
|
|
96
|
+
*,
|
|
97
|
+
indicator: Indicator,
|
|
98
|
+
territory: Territory,
|
|
99
|
+
submesh: MeshLevel,
|
|
100
|
+
flows: bool = False,
|
|
77
101
|
):
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
table_prefix = (
|
|
84
|
-
indicator.flows_db_table_prefix if flows else indicator.db_table_prefix
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
arbo_sub_query = f"""
|
|
88
|
-
SELECT DISTINCT("{mapped_submesh}")
|
|
89
|
-
FROM arborescence_geo arbo
|
|
90
|
-
WHERE arbo."{mapped_mesh}" in('{geo_id_values}')
|
|
91
|
-
"""
|
|
92
|
-
|
|
93
|
-
where = (
|
|
94
|
-
f"""
|
|
95
|
-
WHERE (indic.code_{submesh.lower()}_1 in ({arbo_sub_query})
|
|
96
|
-
OR indic.code_{submesh.lower()}_2 in ({arbo_sub_query}))
|
|
102
|
+
mesh_col = get_mesh_column_name(submesh)
|
|
103
|
+
if submesh == territory.mesh:
|
|
104
|
+
arbo_join = f"""
|
|
105
|
+
JOIN arbo_{submesh} arbo ON arbo.code = indic.{mesh_col} AND arbo.code IN {territory.sql_codes}
|
|
97
106
|
"""
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
107
|
+
else:
|
|
108
|
+
arbo_join = f"""
|
|
109
|
+
JOIN arbo_{territory.mesh}_{submesh} j
|
|
110
|
+
ON j.{submesh} = indic.{mesh_col} AND j.{territory.mesh} IN {territory.sql_codes}
|
|
111
|
+
JOIN arbo_{submesh} arbo
|
|
112
|
+
ON arbo.code = indic.{mesh_col}
|
|
113
|
+
"""
|
|
114
|
+
if flows:
|
|
115
|
+
arbo_join = f"""
|
|
116
|
+
JOIN arbo_{territory.mesh}_{submesh} j1
|
|
117
|
+
ON j1.{submesh} = indic.{mesh_col}_1 AND j1.{territory.mesh} IN {territory.sql_codes}
|
|
118
|
+
JOIN arbo_{submesh} arbo1
|
|
119
|
+
ON arbo1.code = indic.{mesh_col}_1
|
|
120
|
+
|
|
121
|
+
JOIN arbo_{territory.mesh}_{submesh} j2
|
|
122
|
+
ON j2.{submesh} = indic.{mesh_col}_2 AND j2.{territory.mesh} IN {territory.sql_codes}
|
|
123
|
+
JOIN arbo_{submesh} arbo2
|
|
124
|
+
ON arbo2.code = indic.{mesh_col}_2
|
|
101
125
|
"""
|
|
102
|
-
)
|
|
103
126
|
|
|
104
127
|
return f"""
|
|
105
|
-
"{
|
|
106
|
-
{
|
|
107
|
-
{where}
|
|
128
|
+
"{indicator.table_name(submesh, flows=flows)}" indic
|
|
129
|
+
{arbo_join}
|
|
108
130
|
"""
|
|
109
131
|
|
|
110
132
|
|
|
111
133
|
def calculate_aggregate_values(indicator, with_alternative=True):
|
|
112
|
-
# TODO coverage tester avec un indicateur de cette sorte
|
|
113
|
-
# Bastien doit exporter des nouvelles données pour faire le test
|
|
114
134
|
if not indicator.is_composite:
|
|
115
135
|
return "SUM(valeur) as valeur"
|
|
116
136
|
|
|
117
|
-
# TODO coverage tester avec un indicateur de cette sorte
|
|
118
|
-
# Bastien doit exporter des nouvelles données pour faire le test
|
|
119
137
|
if indicator.aggregation_function == AggregationFunctions.DISCRETE_COMPONENT_2:
|
|
120
138
|
sql = f"SUM(composante_1) / COALESCE(NULLIF(SUM(composante_2), 0), 1) * {indicator.aggregation_constant} as valeur"
|
|
121
139
|
if with_alternative:
|
|
@@ -133,45 +151,14 @@ def calculate_aggregate_values(indicator, with_alternative=True):
|
|
|
133
151
|
return sql
|
|
134
152
|
|
|
135
153
|
|
|
136
|
-
def get_territories_ids(main_territory_codes, territory_mesh, submesh):
|
|
137
|
-
mapped_territory_mesh = (
|
|
138
|
-
"DEPCOM" if territory_mesh == "com" else territory_mesh.upper()
|
|
139
|
-
)
|
|
140
|
-
mapped_submesh = "DEPCOM" if submesh == "com" else submesh.upper()
|
|
141
|
-
|
|
142
|
-
query = f"""
|
|
143
|
-
SELECT DISTINCT "{mapped_submesh}" as code
|
|
144
|
-
FROM arborescence_geo
|
|
145
|
-
WHERE "{mapped_territory_mesh}" IN ('{"', '".join(main_territory_codes)}')
|
|
146
|
-
"""
|
|
147
|
-
|
|
148
|
-
territories_ids = [r["code"] for r in run_custom_query(query)]
|
|
149
|
-
return territories_ids
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
def get_sub_territories(territory, submesh):
|
|
153
|
-
territory_codes = territory.id.split(",")
|
|
154
|
-
mapped_territory_mesh = (
|
|
155
|
-
"DEPCOM" if territory.mesh == "com" else territory.mesh.upper()
|
|
156
|
-
)
|
|
157
|
-
mapped_submesh = "DEPCOM" if submesh == "com" else submesh.upper()
|
|
158
|
-
|
|
159
|
-
query = f"""
|
|
160
|
-
SELECT DISTINCT "{mapped_submesh}" as code, "NOM_{mapped_submesh}" as name
|
|
161
|
-
FROM arborescence_geo
|
|
162
|
-
WHERE "{mapped_territory_mesh}" IN ('{"', '".join(territory_codes)}')
|
|
163
|
-
"""
|
|
164
|
-
|
|
165
|
-
return run_custom_query(query)
|
|
166
|
-
|
|
167
|
-
|
|
168
154
|
def get_where_territory(territory):
|
|
169
155
|
territory_id = (
|
|
170
156
|
FRANCE_DB_VALUES[territory.id]
|
|
171
|
-
if territory.mesh == MeshLevel.
|
|
157
|
+
if territory.mesh == MeshLevel.fr
|
|
172
158
|
else territory.id
|
|
173
159
|
)
|
|
174
|
-
|
|
160
|
+
mesh_col = get_mesh_column_name(territory.mesh)
|
|
161
|
+
return f""" "{mesh_col}" = '{territory_id}' """
|
|
175
162
|
|
|
176
163
|
|
|
177
164
|
def get_values_for_territory(indicator, territory, filters=None):
|
|
@@ -189,7 +176,6 @@ def get_values_for_territory(indicator, territory, filters=None):
|
|
|
189
176
|
|
|
190
177
|
|
|
191
178
|
def get_territory_name(territory):
|
|
192
|
-
|
|
193
|
-
query = f"""SELECT "NOM_{territory_mesh}" as nom FROM arborescence_geo WHERE "{territory_mesh}" = '{territory.id}' LIMIT 1;"""
|
|
179
|
+
query = f"""SELECT name FROM arbo_{territory.mesh} WHERE code IN {territory.sql_codes} LIMIT 1;"""
|
|
194
180
|
results = run_custom_query(query)
|
|
195
|
-
return results[0]["
|
|
181
|
+
return results[0]["name"] if results else ""
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
from collections import defaultdict
|
|
2
2
|
|
|
3
|
-
from .commons import
|
|
3
|
+
from .commons import (
|
|
4
|
+
add_optional_filters,
|
|
5
|
+
calculate_aggregate_values,
|
|
6
|
+
get_mesh_column_name,
|
|
7
|
+
)
|
|
4
8
|
from .utils import run_custom_query
|
|
5
9
|
|
|
6
10
|
|
|
@@ -13,12 +17,13 @@ def get_comparison_values_and_buckets(
|
|
|
13
17
|
filters = add_optional_filters(indicator, filters)
|
|
14
18
|
value = calculate_aggregate_values(indicator, with_alternative=False)
|
|
15
19
|
number_of_buckets = min(10, len(territories) + len(cmp_territories))
|
|
20
|
+
mesh_col = get_mesh_column_name(submesh)
|
|
16
21
|
sub_query = f"""
|
|
17
22
|
SELECT
|
|
18
23
|
{value},
|
|
19
|
-
|
|
24
|
+
{mesh_col} as geo_code
|
|
20
25
|
FROM {table_name} indic
|
|
21
|
-
WHERE
|
|
26
|
+
WHERE {mesh_col} IN {territories_sql}
|
|
22
27
|
AND annee = (
|
|
23
28
|
SELECT MAX(annee)
|
|
24
29
|
FROM {table_name}
|
|
@@ -5,7 +5,7 @@ from .commons import (
|
|
|
5
5
|
add_optional_filters,
|
|
6
6
|
calculate_aggregate_values,
|
|
7
7
|
get_last_year,
|
|
8
|
-
|
|
8
|
+
get_mesh_column_name,
|
|
9
9
|
get_where_territory,
|
|
10
10
|
)
|
|
11
11
|
from .utils import get_breakdown_dimension, run_custom_query
|
|
@@ -23,7 +23,6 @@ def get_proportions_chart(indicator, territory, filters):
|
|
|
23
23
|
{add_optional_filters(indicator, filters)}
|
|
24
24
|
GROUP BY "{breakdown_dimension.db_name}"
|
|
25
25
|
"""
|
|
26
|
-
|
|
27
26
|
data = run_custom_query(query)
|
|
28
27
|
filters_color = {f.db_name: f.color for f in breakdown_dimension.filters.all()}
|
|
29
28
|
data_dict = {
|
|
@@ -47,19 +46,15 @@ def get_values_for_submesh_territories(
|
|
|
47
46
|
indicator: Indicator, submesh: MeshLevel, territory: Territory, filters
|
|
48
47
|
):
|
|
49
48
|
submesh = submesh.lower()
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
mesh_col = get_mesh_column_name(submesh)
|
|
50
|
+
parent_territory_join = f"JOIN arbo_{territory.mesh}_{submesh} j ON j.{submesh} = arbo.code AND j.{territory.mesh} IN {territory.sql_codes}"
|
|
51
|
+
if submesh == territory.mesh:
|
|
52
|
+
parent_territory_join = f"AND arbo.code IN {territory.sql_codes}"
|
|
54
53
|
query = f"""
|
|
55
|
-
SELECT {calculate_aggregate_values(indicator)},
|
|
54
|
+
SELECT {calculate_aggregate_values(indicator)}, indic.{mesh_col} as geocode, arbo.name as geoname
|
|
56
55
|
FROM "{indicator.db_table_prefix}_{submesh}" indic
|
|
57
|
-
{
|
|
58
|
-
|
|
59
|
-
SELECT DISTINCT("{mapped_submesh}")
|
|
60
|
-
FROM arborescence_geo arbo
|
|
61
|
-
WHERE arbo."{territory_mesh}" IN ('{geo_ids}')
|
|
62
|
-
)
|
|
56
|
+
JOIN arbo_{submesh} arbo ON arbo.code = indic.{mesh_col}
|
|
57
|
+
{parent_territory_join}
|
|
63
58
|
{add_optional_filters(indicator, filters)}
|
|
64
59
|
AND annee = (
|
|
65
60
|
SELECT MAX(annee)
|
|
@@ -77,7 +77,6 @@ def get_indicator_histogram_data(indicator, territory, submesh, filters):
|
|
|
77
77
|
territory_values = get_values_for_submesh_territories(
|
|
78
78
|
indicator, submesh, territory, filters
|
|
79
79
|
)
|
|
80
|
-
print("!!", territory_values)
|
|
81
80
|
datasets_histogram_bar_chart, deciles = get_territories_histogram_data(
|
|
82
81
|
territory_values, indicator.unite
|
|
83
82
|
)
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
from .commons import
|
|
1
|
+
from .commons import (
|
|
2
|
+
generate_aggregate_query_for_location,
|
|
3
|
+
get_mesh_column_name,
|
|
4
|
+
)
|
|
2
5
|
from .utils import run_custom_query
|
|
3
6
|
|
|
4
7
|
|
|
@@ -29,15 +32,16 @@ def get_min_max_statistics(indicator, submesh):
|
|
|
29
32
|
|
|
30
33
|
|
|
31
34
|
def get_values_for(extremum, submesh, is_alternative=False):
|
|
35
|
+
mesh_col = get_mesh_column_name(submesh)
|
|
32
36
|
return f"""
|
|
33
37
|
{extremum}_value,
|
|
34
38
|
(
|
|
35
|
-
SELECT
|
|
39
|
+
SELECT {mesh_col} AS code_{extremum}
|
|
36
40
|
FROM aggregat
|
|
37
41
|
WHERE valeur{"_alternative" if is_alternative else ""} = (SELECT * FROM {extremum}_value) LIMIT 1
|
|
38
42
|
) AS code_{extremum},
|
|
39
43
|
(
|
|
40
|
-
SELECT count(
|
|
44
|
+
SELECT count({mesh_col}) AS count_{extremum}
|
|
41
45
|
FROM aggregat
|
|
42
46
|
WHERE valeur{"_alternative" if is_alternative else ""} = (SELECT * FROM {extremum}_value)
|
|
43
47
|
) AS count_{extremum},
|
|
@@ -73,12 +77,13 @@ def get_names_from_codes(dict_result, submesh):
|
|
|
73
77
|
for key, value in dict_result.items():
|
|
74
78
|
if key.startswith("code_"):
|
|
75
79
|
codes_to_fetch.append(value)
|
|
76
|
-
|
|
80
|
+
codes = ", ".join(f"'{code.strip()}'" for code in codes_to_fetch)
|
|
77
81
|
query = f"""
|
|
78
|
-
SELECT
|
|
79
|
-
FROM
|
|
80
|
-
WHERE
|
|
82
|
+
SELECT code, name
|
|
83
|
+
FROM arbo_{submesh}
|
|
84
|
+
WHERE code IN ({codes});
|
|
81
85
|
"""
|
|
86
|
+
|
|
82
87
|
rows = run_custom_query(query)
|
|
83
88
|
names_dict = {}
|
|
84
89
|
for row in rows:
|
|
@@ -4,7 +4,8 @@ from .commons import (
|
|
|
4
4
|
add_optional_filters,
|
|
5
5
|
calculate_aggregate_values,
|
|
6
6
|
get_last_year,
|
|
7
|
-
|
|
7
|
+
get_mesh_column_name,
|
|
8
|
+
get_values_for_indicator_territory_submesh,
|
|
8
9
|
)
|
|
9
10
|
from .utils import get_breakdown_dimension, run_custom_query
|
|
10
11
|
|
|
@@ -14,29 +15,30 @@ def breakdown_territories(indicator, submesh, year, filters, top_10_territories)
|
|
|
14
15
|
[f"'{territory['code_geo']}'" for territory in top_10_territories]
|
|
15
16
|
)
|
|
16
17
|
breakdown_dimension = get_breakdown_dimension(indicator).db_name
|
|
17
|
-
|
|
18
|
+
mesh_col = get_mesh_column_name(submesh)
|
|
18
19
|
query = f"""
|
|
19
20
|
SELECT {calculate_aggregate_values(indicator, with_alternative=False)},
|
|
20
21
|
"{breakdown_dimension}" as dimension,
|
|
21
|
-
"
|
|
22
|
+
"{mesh_col}" as code_geo
|
|
22
23
|
FROM "{indicator.db_table_prefix}_{submesh}" as indic
|
|
23
|
-
WHERE
|
|
24
|
+
WHERE {mesh_col} in ({territories_code}) AND annee = {year}
|
|
24
25
|
{add_optional_filters(indicator, filters)}
|
|
25
|
-
GROUP BY "
|
|
26
|
+
GROUP BY "{mesh_col}", "{breakdown_dimension}"
|
|
26
27
|
"""
|
|
27
28
|
results = run_custom_query(query)
|
|
28
29
|
return results
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
def get_top_10_territories(indicator, territory, submesh, year, filters):
|
|
33
|
+
mesh_col = get_mesh_column_name(submesh)
|
|
32
34
|
query = f"""
|
|
33
35
|
SELECT {calculate_aggregate_values(indicator, with_alternative=False)},
|
|
34
|
-
indic.
|
|
35
|
-
FROM {
|
|
36
|
+
indic.{mesh_col} as code_geo, arbo.name
|
|
37
|
+
FROM {get_values_for_indicator_territory_submesh(indicator=indicator, territory=territory, submesh=submesh)}
|
|
36
38
|
{add_optional_filters(indicator, filters)}
|
|
37
39
|
AND annee = {year}
|
|
38
40
|
AND valeur IS NOT NULL
|
|
39
|
-
GROUP BY
|
|
41
|
+
GROUP BY indic.{mesh_col}, arbo.name
|
|
40
42
|
ORDER BY valeur DESC
|
|
41
43
|
LIMIT 10
|
|
42
44
|
"""
|
|
@@ -78,8 +80,6 @@ def get_indicator_top_10_data(indicator, territory, submesh, filters):
|
|
|
78
80
|
}
|
|
79
81
|
for f in breakdown_filters
|
|
80
82
|
]
|
|
81
|
-
# TODO coverage faire un test avec un indicateur qui n'a pas de dimensions
|
|
82
|
-
# necessite un export de données de Bastien
|
|
83
83
|
else:
|
|
84
84
|
datasets_top_bar_chart = [
|
|
85
85
|
{
|
|
@@ -88,12 +88,12 @@ def get_indicator_top_10_data(indicator, territory, submesh, filters):
|
|
|
88
88
|
}
|
|
89
89
|
]
|
|
90
90
|
|
|
91
|
-
labels_top_bar_chart = [territory["
|
|
91
|
+
labels_top_bar_chart = [territory["name"] for territory in territories]
|
|
92
92
|
|
|
93
93
|
csv_data = []
|
|
94
94
|
for territory in territories:
|
|
95
95
|
csv_row = {}
|
|
96
|
-
csv_row["Territoire"] = territory["
|
|
96
|
+
csv_row["Territoire"] = territory["name"]
|
|
97
97
|
csv_row["Code Géographique"] = territory["code_geo"]
|
|
98
98
|
csv_row[f"Valeur {indicator.unite}"] = territory["valeur"]
|
|
99
99
|
if breakdown_dimension:
|
|
@@ -2,6 +2,15 @@ from django.conf import settings
|
|
|
2
2
|
from django.db import connections
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
def format_sql_codes(codes: list[str]):
|
|
6
|
+
"""
|
|
7
|
+
Format list of IDs for SQL IN statement.
|
|
8
|
+
["1","2","3"] => ('1', '2', '3')
|
|
9
|
+
"""
|
|
10
|
+
codes = ", ".join(f"'{code.strip()}'" for code in codes)
|
|
11
|
+
return f"({codes})"
|
|
12
|
+
|
|
13
|
+
|
|
5
14
|
def get_breakdown_dimension(indicator):
|
|
6
15
|
breakdown_dimension = (
|
|
7
16
|
indicator.dimensions.filter(is_breakdown=True).first()
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
from .payloads import IndicatorTablePayload
|
|
2
|
-
from .query.commons import
|
|
2
|
+
from .query.commons import (
|
|
3
|
+
add_optional_filters,
|
|
4
|
+
get_values_for_indicator_territory_submesh,
|
|
5
|
+
)
|
|
3
6
|
from .query.utils import run_custom_query
|
|
4
7
|
|
|
5
8
|
|
|
@@ -22,10 +25,10 @@ def _get_query(
|
|
|
22
25
|
)
|
|
23
26
|
)
|
|
24
27
|
territory_search_where = (
|
|
25
|
-
"OR (unaccent(LOWER(
|
|
28
|
+
"OR (unaccent(LOWER(arbo1.name)) LIKE unaccent(LOWER(CONCAT('%%', %(search)s, '%%')))) OR (unaccent(LOWER(arbo2.name)) LIKE unaccent(LOWER(CONCAT('%%', %(search)s, '%%'))))"
|
|
26
29
|
if props.flows
|
|
27
30
|
else (
|
|
28
|
-
"OR (unaccent(LOWER(
|
|
31
|
+
"OR (unaccent(LOWER(name)) LIKE unaccent(LOWER(CONCAT('%%', %(search)s, '%%'))))"
|
|
29
32
|
)
|
|
30
33
|
)
|
|
31
34
|
where = (
|
|
@@ -48,7 +51,7 @@ def _get_query(
|
|
|
48
51
|
SELECT
|
|
49
52
|
{", ".join(columns)}
|
|
50
53
|
FROM
|
|
51
|
-
{
|
|
54
|
+
{get_values_for_indicator_territory_submesh(indicator=indicator, territory=props.territory, submesh=props.submesh, flows=props.flows)}
|
|
52
55
|
{regular_dimensions_filters}
|
|
53
56
|
{where} {where_year}
|
|
54
57
|
{order_clause}
|
|
@@ -60,18 +63,18 @@ def get_values_columns(indicator, props, *, for_export=False):
|
|
|
60
63
|
if props.flows:
|
|
61
64
|
columns = [
|
|
62
65
|
"annee",
|
|
63
|
-
"territory_1",
|
|
64
|
-
"territory_2",
|
|
66
|
+
"arbo1.name as territory_1",
|
|
67
|
+
"arbo2.name as territory_2",
|
|
65
68
|
f"{indicator.flows_dimension} AS dimension"
|
|
66
69
|
if indicator.flows_dimension
|
|
67
70
|
else None,
|
|
68
71
|
"CAST(valeur AS int) as valeur",
|
|
69
72
|
]
|
|
70
73
|
if for_export:
|
|
71
|
-
columns += ["territory_1_id", "territory_2_id"]
|
|
74
|
+
columns += ["arbo1.code as territory_1_id", "arbo2.code as territory_2_id"]
|
|
72
75
|
else:
|
|
73
76
|
columns = (
|
|
74
|
-
["annee", "
|
|
77
|
+
["annee", "name"]
|
|
75
78
|
+ [f"{dimension.db_name}" for dimension in indicator.dimensions.all()]
|
|
76
79
|
+ [
|
|
77
80
|
f"valeur * {indicator.aggregation_constant if indicator.unite == '%' else 1} AS valeur",
|
|
@@ -81,17 +84,17 @@ def get_values_columns(indicator, props, *, for_export=False):
|
|
|
81
84
|
]
|
|
82
85
|
)
|
|
83
86
|
if for_export:
|
|
84
|
-
columns += ["
|
|
87
|
+
columns += ["code"]
|
|
85
88
|
return columns
|
|
86
89
|
|
|
87
90
|
|
|
88
91
|
def get_values_orders(indicator, props: IndicatorTablePayload):
|
|
89
92
|
territory_order = None
|
|
90
|
-
if props.column_order not in ["
|
|
93
|
+
if props.column_order not in ["name", "arbo1.name", "arbo2.name"]:
|
|
91
94
|
territory_order = (
|
|
92
|
-
"LOWER(
|
|
95
|
+
"LOWER(arbo1.name) ASC, LOWER(arbo2.name) ASC"
|
|
93
96
|
if props.flows
|
|
94
|
-
else "LOWER(
|
|
97
|
+
else "LOWER(name) ASC"
|
|
95
98
|
)
|
|
96
99
|
year_order = "annee DESC" if props.column_order != "annee" else None
|
|
97
100
|
dimension_order = None
|