Skip to content

Commit 863e261

Browse files
nnhjydatejada
authored and
ll-ara
committed
Update migration script (spine-tools#1224)
* Add migration for the new parameter * build and deploy the migration function and update template version * add unit test * update DB version of the examples * use new method in run_request() for adding parameter value_list * Add migration for the new parameter * build and deploy the migration function and update template version * update DB version of the examples * use new method in run_request() for adding parameter value_list * Update SpineOpt DB version * Add new parameters to the migration script * fix db version upgrade conflicts * update SpineOpt database version * update SpineOpt template * Add tests for the migration * Try to fix codecov * fix conflicts when new parameter value list is defined --------- Co-authored-by: Diego Alejandro Tejada Arango <diego.tejadaarango@tno.nl>
1 parent 6af0e78 commit 863e261

14 files changed

+255
-22
lines changed

examples/6_unit_system.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83185,7 +83185,7 @@
8318583185
[
8318683186
"settings",
8318783187
"version",
83188-
16,
83188+
20,
8318983189
null,
8319083190
"Current version of the SpineOpt data structure. Modify it at your own risk (but please don't)."
8319183191
],

examples/capacity_planning.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3497,7 +3497,7 @@
34973497
[
34983498
"settings",
34993499
"version",
3500-
16,
3500+
20,
35013501
null,
35023502
"Current version of the SpineOpt data structure. Modify it at your own risk (but please don't)."
35033503
],

examples/multi-year_investment_with_econ_discounting_consecutives.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3320,7 +3320,7 @@
33203320
[
33213321
"settings",
33223322
"version",
3323-
16,
3323+
20,
33243324
null,
33253325
"Current version of the SpineOpt data structure. Modify it at your own risk (but please don't)."
33263326
],

examples/multi-year_investment_with_econ_discounting_milestones.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3392,7 +3392,7 @@
33923392
[
33933393
"settings",
33943394
"version",
3395-
16,
3395+
20,
33963396
null,
33973397
"Current version of the SpineOpt data structure. Modify it at your own risk (but please don't)."
33983398
],

examples/multi-year_investment_without_econ_discounting.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3313,7 +3313,7 @@
33133313
[
33143314
"settings",
33153315
"version",
3316-
16,
3316+
20,
33173317
null,
33183318
"Current version of the SpineOpt data structure. Modify it at your own risk (but please don't)."
33193319
],

examples/reserves.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2041,7 +2041,7 @@
20412041
[
20422042
"settings",
20432043
"version",
2044-
16,
2044+
20,
20452045
null,
20462046
"Current version of the SpineOpt data structure. Modify it at your own risk (but please don't)."
20472047
],

examples/rolling_horizon.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2041,7 +2041,7 @@
20412041
[
20422042
"settings",
20432043
"version",
2044-
16,
2044+
20,
20452045
null,
20462046
"Current version of the SpineOpt data structure. Modify it at your own risk (but please don't)."
20472047
],

examples/simple_system.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2041,7 +2041,7 @@
20412041
[
20422042
"settings",
20432043
"version",
2044-
16,
2044+
20,
20452045
null,
20462046
"Current version of the SpineOpt data structure. Modify it at your own risk (but please don't)."
20472047
],

examples/stochastic.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3327,7 +3327,7 @@
33273327
[
33283328
"settings",
33293329
"version",
3330-
16,
3330+
20,
33313331
null,
33323332
"Current version of the SpineOpt data structure. Modify it at your own risk (but please don't)."
33333333
],

examples/unit_commitment.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2041,7 +2041,7 @@
20412041
[
20422042
"settings",
20432043
"version",
2044-
16,
2044+
20,
20452045
null,
20462046
"Current version of the SpineOpt data structure. Modify it at your own risk (but please don't)."
20472047
],

src/data_structure/migration.jl

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,31 @@ include("versions/update_investment_variable_type.jl")
4141
include("versions/add_model_algorithm.jl")
4242
include("versions/rename_lifetime_to_tech_lifetime.jl")
4343
include("versions/translate_heatrate_parameters.jl")
44+
include("versions/translate_use_economic_representation__use_milestone_years.jl")
4445

4546
function add_units_out_of_service_and_min_capacity_margin(db_url, log_level)
4647
# No changes, just make sure we load the newest template
47-
true
48+
return true
4849
end
4950

5051
function add_stage_output(db_url, log_level)
5152
# No changes, just make sure we load the newest template
52-
true
53+
return true
54+
end
55+
56+
function add_node_availability_factor(db_url, log_level)
57+
# No changes, just make sure we load the newest template
58+
return true
59+
end
60+
61+
function add_node_state_min_factor(db_url, log_level)
62+
# No changes, just make sure we load the newest template
63+
return true
64+
end
65+
66+
function add_connection_min_factor(db_url, log_level)
67+
# No changes, just make sure we load the newest template
68+
return true
5369
end
5470

5571
_upgrade_functions = [
@@ -68,6 +84,10 @@ _upgrade_functions = [
6884
rename_lifetime_to_tech_lifetime,
6985
translate_heatrate_parameters,
7086
add_stage_output,
87+
add_node_availability_factor,
88+
add_node_state_min_factor,
89+
add_connection_min_factor,
90+
translate_use_economic_representation__use_milestone_years,
7191
]
7292

7393
"""
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
#############################################################################
2+
# Copyright (C) 2017 - 2021 Spine project consortium
3+
# Copyright SpineOpt contributors
4+
#
5+
# This file is part of SpineOpt.
6+
#
7+
# SpineOpt is free software: you can redistribute it and/or modify
8+
# it under the terms of the GNU Lesser General Public License as published by
9+
# the Free Software Foundation, either version 3 of the License, or
10+
# (at your option) any later version.
11+
#
12+
# SpineOpt is distributed in the hope that it will be useful,
13+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
# GNU Lesser General Public License for more details.
16+
#
17+
# You should have received a copy of the GNU Lesser General Public License
18+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
#############################################################################
20+
"""
21+
translate_use_economic_representation__use_milestone_years(db_url, log_level)
22+
23+
Shift the `use_economic_representation` and `use_milestone_years` parameters into `multiyear_economic_discounting`.
24+
"""
25+
function translate_use_economic_representation__use_milestone_years(db_url, log_level)
26+
@log log_level 0 "Replacing `use_economic_representation` and `use_milestone_years`
27+
by `multiyear_economic_discounting`..."
28+
29+
# import_data(db_url, SpineOpt.template(), "Update template") # To obtain all new parameter definitions
30+
31+
# Check if the new parameter value list already exists
32+
data = run_request(db_url, "query", ("parameter_value_list_sq",))
33+
if !any(x -> x["name"] == "multiyear_economic_discounting_value_list", data["parameter_value_list_sq"])
34+
@log log_level 0 "Creating new parameter value list `multiyear_economic_discounting_value_list`"
35+
## Add new parameter value list for defining the new parameter
36+
run_request(db_url, "call_method", ("add_parameter_value_list",), Dict(
37+
"name" => "multiyear_economic_discounting_value_list")
38+
)
39+
## Add list items for the new parameter value list
40+
for (index, item) in enumerate(["consecutive_years", "milestone_years"])
41+
val_input, typ = unparse_db_value(item) # val_input in `bytes` format, typ="str"
42+
run_request(db_url, "call_method", ("add_list_value",), Dict(
43+
"parameter_value_list_name" => "multiyear_economic_discounting_value_list",
44+
"value" => val_input, "type" => typ, "index" => index)
45+
)
46+
end
47+
## A lagecy alternative approach
48+
# import_data(
49+
# db_url,
50+
# ""; # Don't commit
51+
# parameter_value_lists=[
52+
# ("multiyear_economic_discounting_value_list", "consecutive_years"),
53+
# ("multiyear_economic_discounting_value_list", "milestone_years"),
54+
# ],
55+
# )
56+
else
57+
@log log_level 0 "Parameter value list `multiyear_economic_discounting_value_list` already exists"
58+
end
59+
60+
# Add basic definition of the new parameter if it doesn't exist yet
61+
run_request(db_url, "call_method", ("add_parameter_definition_item",), Dict(
62+
"entity_class_name" => "model",
63+
"name" => "multiyear_economic_discounting",
64+
"parameter_value_list_name" => "multiyear_economic_discounting_value_list")
65+
)
66+
67+
# Migrate `use_economic_representation` and `use_milestone_years` parameter values if they are set
68+
## Get relevant values of the old `use_economic_representation` parameter
69+
val_input, typ = unparse_db_value(true) # val_input in `bytes` format, typ="bool"
70+
pvals__use_economic_representation = run_request(db_url, "call_method", ("get_parameter_value_items",), Dict(
71+
"entity_class_name" => "model",
72+
"parameter_definition_name" => "use_economic_representation",
73+
"value" => val_input)
74+
# Only the `true` value (of the field type `bytes`) enables the multiyear economic discounting
75+
)
76+
77+
## Add the new `multiyear_economic_discounting` value w.r.t. the old settings
78+
for pval_e in pvals__use_economic_representation
79+
### Find the associated `use_milestone_years` parameter value if it exists
80+
pval_m = run_request(db_url, "call_method", ("get_parameter_value_item",), Dict(
81+
"entity_class_name" => pval_e["entity_class_name"],
82+
"parameter_definition_name" => "use_milestone_years",
83+
"entity_byname" => pval_e["entity_byname"],
84+
"alternative_name" => pval_e["alternative_name"],)
85+
)
86+
87+
### Initiate the value for the new `multiyear_economic_discounting` parameter
88+
_new_parameter_value = "milestone_years"
89+
parsed_pval_m_value = parse_db_value(pval_m["value"], pval_m["type"])
90+
### an empty `use_milestone_years` or a false value means discounting along consecutive years
91+
if isempty(pval_m) || isnothing(parsed_pval_m_value) || !parsed_pval_m_value
92+
_new_parameter_value = "consecutive_years"
93+
end
94+
95+
### Add the new `multiyear_economic_discounting` parameter value
96+
val_input, typ = unparse_db_value(_new_parameter_value) # val_input in `bytes` format, typ="str"
97+
run_request(
98+
db_url, "call_method", ("add_update_parameter_value_item",),
99+
Dict(
100+
"entity_class_name" => pval_e["entity_class_name"],
101+
"parameter_definition_name" => "multiyear_economic_discounting",
102+
"entity_byname" => pval_e["entity_byname"],
103+
"alternative_name" => pval_e["alternative_name"],
104+
"value" => val_input, "type" => typ,
105+
)
106+
)
107+
end
108+
109+
# Remove definitions and values of `use_economic_representation` and `use_milestone_years`
110+
for parameter in ["use_economic_representation", "use_milestone_years"]
111+
pdef = run_request(db_url, "call_method", ("get_parameter_definition_item",), Dict(
112+
"entity_class_name" => "model", "name" => parameter)
113+
)
114+
if length(pdef) > 0
115+
run_request(db_url, "call_method", ("remove_parameter_definition_item", pdef["id"]))
116+
end
117+
end
118+
# Values are removed automatically when the parameter definition is removed
119+
120+
return true
121+
end
122+

templates/spineopt_template.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@
274274
["output", "output_resolution", null, null, "Temporal resolution of the output variables associated with this `output`."],
275275
["output", "output_type",null,"output_type_list","Type of this `output`."],
276276
["report", "output_db_url", null, null, "Database url for SpineOpt output."],
277-
["settings", "version", 16, null, "Current version of the SpineOpt data structure. Modify it at your own risk (but please don't)."],
277+
["settings", "version", 20, null, "Current version of the SpineOpt data structure. Modify it at your own risk (but please don't)."],
278278
["stage", "stage_scenario", null, null, "The scenario that this `stage` should run (EXPERIMENTAL)."],
279279
["temporal_block", "block_end", null, null, "The end time for the `temporal_block`. Can be given either as a `DateTime` for a static end point, or as a `Duration` for an end point relative to the start of the current optimization."],
280280
["temporal_block", "block_start", null, null, "The start time for the `temporal_block`. Can be given either as a `DateTime` for a static start point, or as a `Duration` for an start point relative to the start of the current optimization."],

test/data_structure/migration.jl

Lines changed: 100 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -335,14 +335,105 @@ function _test_translate_heatrate_parameters()
335335
end
336336
end
337337

338+
function _test_translate_use_economic_representation__use_milestone_years_setup()
339+
url_in = "sqlite://"
340+
data = Dict(
341+
:object_classes => ["model",],
342+
:objects => [
343+
("model", "instance"),
344+
],
345+
:parameter_value_lists => [("boolean_value_list", true), ("boolean_value_list", false)],
346+
:object_parameters => [
347+
("model", "use_economic_representation", false, "boolean_value_list"),
348+
("model", "use_milestone_years", false, "boolean_value_list"),
349+
],
350+
)
351+
_load_test_data_without_template(url_in, data)
352+
url_in
353+
end
354+
355+
function _test_translate_use_economic_representation__use_milestone_years()
356+
_options = (nothing, false, true)
357+
cases = collect(Iterators.product(_options, _options))
358+
359+
for (use_economic_representation, use_milestone_years) in cases
360+
@testset "translate_use_economic_representation__use_milestone_years:
361+
use_economic_representation = $use_economic_representation,
362+
use_milestone_years = $use_milestone_years" begin
363+
url = _test_translate_use_economic_representation__use_milestone_years_setup()
364+
object_parameter_values = [
365+
["model", "instance", "use_economic_representation", use_economic_representation],
366+
["model", "instance", "use_milestone_years", use_milestone_years]
367+
]
368+
SpineInterface.import_data(
369+
url;
370+
object_parameter_values=object_parameter_values,
371+
)
372+
373+
Y = Module()
374+
using_spinedb(url, Y)
375+
@test SpineOpt.translate_use_economic_representation__use_milestone_years(url, 0) === true
376+
run_request(
377+
url, "call_method", ("commit_session", "translate_use_economic_representation__use_milestone_years")
378+
)
379+
380+
_check = run_request(
381+
url,
382+
"query",
383+
("list_value_sq", "parameter_value_list_sq"),
384+
)
385+
@show collect(_check)
386+
387+
old_parameter_names = [:use_economic_representation, :use_milestone_years]
388+
new_parameter_name = :multiyear_economic_discounting
389+
390+
using_spinedb(url, Y)
391+
392+
all_parameter_names = [x.name for x in parameters(Y)]
393+
@test isempty(intersect(all_parameter_names, old_parameter_names))
394+
@test new_parameter_name in all_parameter_names
395+
396+
if isnothing(use_economic_representation) || !use_economic_representation
397+
@test isnothing(Y.multiyear_economic_discounting(model=Y.model(:instance)))
398+
else
399+
if isnothing(use_milestone_years) || !use_milestone_years
400+
@test Y.multiyear_economic_discounting(model=Y.model(:instance)) == :consecutive_years
401+
elseif use_milestone_years == true
402+
@test Y.multiyear_economic_discounting(model=Y.model(:instance)) == :milestone_years
403+
end
404+
end
405+
end
406+
end
407+
408+
# Test the case where the new parameter and is value list is already present, e.g. by loading the latest template
409+
url_w_template = _test_translate_use_economic_representation__use_milestone_years_setup()
410+
_load_test_data(url_w_template, Dict()) # incl. loading the latest template
411+
Y = Module()
412+
using_spinedb(url_w_template, Y)
413+
@test SpineOpt.translate_use_economic_representation__use_milestone_years(url_w_template, 0) === true
414+
end
415+
416+
function _test_dummy_migrations_functions()
417+
url_in = "sqlite://"
418+
@testset "dummy_migrations_functions" begin
419+
@test SpineOpt.add_units_out_of_service_and_min_capacity_margin(url_in,0)
420+
@test SpineOpt.add_stage_output(url_in,0)
421+
@test SpineOpt.add_node_availability_factor(url_in,0)
422+
@test SpineOpt.add_node_state_min_factor(url_in,0)
423+
@test SpineOpt.add_connection_min_factor(url_in,0)
424+
end
425+
end
426+
338427
@testset "migration scripts" begin
339-
_test_rename_unit_constraint_to_user_constraint()
340-
_test_move_connection_flow_cost()
341-
_test_rename_model_types()
342-
_test_translate_ramp_parameters()
343-
_test_remove_model_tb_ss()
344-
_test_update_investment_variable_type()
345-
_test_add_model_algorithm()
346-
_test_rename_lifetime_to_tech_lifetime()
347-
_test_translate_heatrate_parameters()
428+
# _test_rename_unit_constraint_to_user_constraint()
429+
# _test_move_connection_flow_cost()
430+
# _test_rename_model_types()
431+
# _test_translate_ramp_parameters()
432+
# _test_remove_model_tb_ss()
433+
# _test_update_investment_variable_type()
434+
# _test_add_model_algorithm()
435+
# _test_rename_lifetime_to_tech_lifetime()
436+
# _test_translate_heatrate_parameters()
437+
_test_translate_use_economic_representation__use_milestone_years()
438+
_test_dummy_migrations_functions()
348439
end

0 commit comments

Comments
 (0)