Skip to content

Commit

Permalink
Merge branch 'parameter_manager_events' (#211)
Browse files Browse the repository at this point in the history
  • Loading branch information
jsvgoncalves committed Nov 21, 2024
2 parents aef9697 + 5470729 commit 0e66147
Show file tree
Hide file tree
Showing 6 changed files with 364 additions and 35 deletions.
50 changes: 30 additions & 20 deletions bw2data/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -1106,7 +1106,7 @@ def recalculate(group):
return ActivityParameter.recalculate_exchanges(group)


class Group(Model):
class Group(SnowflakeIDBaseClass):
name = TextField(unique=True)
fresh = BooleanField(default=True)
updated = DateTimeField(default=datetime.datetime.now)
Expand Down Expand Up @@ -1187,10 +1187,12 @@ def add_to_group(self, group, activity):
return

# Avoid duplicate by deleting existing parameters
ActivityParameter.delete().where(
# Call in loop to get event handling
for ap in ActivityParameter.select().where(
ActivityParameter.database == activity["database"],
ActivityParameter.code == activity["code"],
).execute()
):
ap.delete_instance()

def reformat(o):
skipped = ("name", "amount", "formula")
Expand Down Expand Up @@ -1258,10 +1260,12 @@ def drop_fields(dct):

with self.db.atomic():
self.remove_exchanges_from_group(group, activity, restore_amounts)
ActivityParameter.delete().where(
# Call in loop to get event handling
for ap in ActivityParameter.select().where(
ActivityParameter.database == activity[0],
ActivityParameter.code == activity[1],
).execute()
):
ap.delete_instance()
activity.save()

def add_exchanges_to_group(self, group, activity):
Expand Down Expand Up @@ -1315,10 +1319,12 @@ def remove_exchanges_from_group(self, group, activity, restore_original=True):
del exc["original_amount"]
exc.save()

ParameterizedExchange.delete().where(ParameterizedExchange.group == group).execute()
# Call in loop to get event handling
for pe in ParameterizedExchange.select().where(ParameterizedExchange.group == group):
pe.delete_instance()

def new_project_parameters(self, data, overwrite=True):
"""Efficiently and correctly enter multiple parameters.
"""Correctly enter multiple parameters.
Will overwrite existing project parameters with the same name, unless ``overwrite`` is false, in which case a ``ValueError`` is raised.
Expand Down Expand Up @@ -1361,14 +1367,16 @@ def reformat(ds):

with self.db.atomic():
# Remove existing values
ProjectParameter.delete().where(ProjectParameter.name << tuple(new)).execute()
for idx in range(0, len(data), 100):
ProjectParameter.insert_many(data[idx : idx + 100]).execute()
# Call in loop to get event handling
for pp in ProjectParameter.select().where(ProjectParameter.name << tuple(new)):
pp.delete_instance()
for dataset in data:
ProjectParameter.create(**dataset)
Group.get_or_create(name="project")[0].expire()
ProjectParameter.recalculate()

def new_database_parameters(self, data, database, overwrite=True):
"""Efficiently and correctly enter multiple parameters. Deletes **all** existing database parameters for this database.
"""Correctly enter multiple parameters. Deletes **all** existing database parameters for this database.
Will overwrite existing database parameters with the same name, unless ``overwrite`` is false, in which case a ``ValueError`` is raised.
Expand Down Expand Up @@ -1419,17 +1427,18 @@ def reformat(ds):

with self.db.atomic():
# Remove existing values
DatabaseParameter.delete().where(
for dp in DatabaseParameter.select().where(
DatabaseParameter.database == database,
DatabaseParameter.name << tuple(new),
).execute()
for idx in range(0, len(data), 100):
DatabaseParameter.insert_many(data[idx : idx + 100]).execute()
):
dp.delete_instance()
for dataset in data:
DatabaseParameter.create(**dataset)
Group.get_or_create(name=database)[0].expire()
DatabaseParameter.recalculate(database)

def new_activity_parameters(self, data, group, overwrite=True):
"""Efficiently and correctly enter multiple parameters. Deletes **all** existing activity parameters for this group.
"""Correctly enter multiple parameters. Deletes **all** existing activity parameters for this group.
Will overwrite existing parameters in the same group with the same name, unless ``overwrite`` is false, in which case a ``ValueError`` is raised.
Expand Down Expand Up @@ -1490,11 +1499,12 @@ def reformat(ds):

with self.db.atomic():
# Remove existing values
ActivityParameter.delete().where(
for ap in ActivityParameter.select().where(
ActivityParameter.group == group, ActivityParameter.name << new
).execute()
for idx in range(0, len(data), 100):
ActivityParameter.insert_many(data[idx : idx + 100]).execute()
):
ap.delete_instance()
for dataset in data:
ActivityParameter.create(**dataset)
Group.get_or_create(name=group)[0].expire()
ActivityParameter.recalculate(group)

Expand Down
23 changes: 18 additions & 5 deletions bw2data/revisions.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from bw2data.parameters import (
ActivityParameter,
DatabaseParameter,
Group,
ParameterBase,
ParameterizedExchange,
ProjectParameter,
Expand Down Expand Up @@ -185,15 +186,19 @@ def generate(
label = SIGNALLEDOBJECT_TO_LABEL[obj_type]
handler = REVISIONED_LABEL_AS_OBJECT[label]

diff = deepdiff.DeepDiff(
handler.current_state_as_dict(old) if old else None,
handler.current_state_as_dict(new) if new else None,
verbose_level=2,
)
if not diff:
return None

return cls.from_difference(
label,
old.id if old is not None else new.id,
change_type,
deepdiff.DeepDiff(
handler.current_state_as_dict(old) if old else None,
handler.current_state_as_dict(new) if new else None,
verbose_level=2,
),
diff,
)


Expand Down Expand Up @@ -322,6 +327,12 @@ def _unwrap_diff_dict(cls, data: dict) -> dict:
}


class RevisionedGroup(RevisionedParameter):
KEYS = ("id", "name", "order")
ORM_CLASS = Group
# Implicitly skips `fresh` and `updated` fields because they are in `KEYS`.


class RevisionedParameterizedExchange(RevisionedParameter):
KEYS = ("id", "group", "formula", "exchange")
ORM_CLASS = ParameterizedExchange
Expand Down Expand Up @@ -465,6 +476,7 @@ def handle(cls, revision_data: dict) -> None:
DatabaseParameter: "database_parameter",
ActivityParameter: "activity_parameter",
ParameterizedExchange: "parameterized_exchange",
Group: "group",
}
REVISIONED_LABEL_AS_OBJECT = {
"lci_node": RevisionedNode,
Expand All @@ -474,5 +486,6 @@ def handle(cls, revision_data: dict) -> None:
"database_parameter": RevisionedDatabaseParameter,
"activity_parameter": RevisionedActivityParameter,
"parameterized_exchange": RevisionedParameterizedExchange,
"group": RevisionedGroup,
}
REVISIONS_OBJECT_AS_LABEL = {v: k for k, v in REVISIONED_LABEL_AS_OBJECT.items()}
27 changes: 25 additions & 2 deletions tests/unit/test_activity_parameter_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@


@bw2test
def test_activity_parameter_revision_expected_format_create(num_revisions):
def test_activity_parameter_revision_expected_format_create(num_revisions, monkeypatch):
def no_signal_save(self, *args, **kwargs):
kwargs["signal"] = False
return super(Group, self).save(*args, **kwargs)

monkeypatch.setattr(Group, "save", no_signal_save)

projects.set_current("activity-event")

assert not ActivityParameter.select().count()
Expand All @@ -27,6 +33,17 @@ def test_activity_parameter_revision_expected_format_create(num_revisions):
amount=5,
data={"foo": "bar"},
)

from pprint import pprint

pprint(
[
json.load(open(fp))
for fp in (projects.dataset.dir / "revisions").iterdir()
if fp.stem.lower() != "head" and fp.is_file()
]
)

assert dp.id > 1e6
assert num_revisions(projects) == 1

Expand Down Expand Up @@ -73,7 +90,13 @@ def test_activity_parameter_revision_expected_format_create(num_revisions):


@bw2test
def test_activity_parameter_revision_apply_create(num_revisions):
def test_activity_parameter_revision_apply_create(num_revisions, monkeypatch):
def no_signal_save(self, *args, **kwargs):
kwargs["signal"] = False
return super(Group, self).save(*args, **kwargs)

monkeypatch.setattr(Group, "save", no_signal_save)

projects.set_current("activity-event")
DatabaseChooser("test-database").register()
assert projects.dataset.revision is None
Expand Down
18 changes: 15 additions & 3 deletions tests/unit/test_database_parameter_events.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import json

from bw2data.database import DatabaseChooser
from bw2data.parameters import DatabaseParameter
from bw2data.parameters import DatabaseParameter, Group
from bw2data.project import projects
from bw2data.snowflake_ids import snowflake_id_generator
from bw2data.tests import bw2test


@bw2test
def test_database_parameter_revision_expected_format_create(num_revisions):
def test_database_parameter_revision_expected_format_create(num_revisions, monkeypatch):
def no_signal_save(self, *args, **kwargs):
kwargs["signal"] = False
return super(Group, self).save(*args, **kwargs)

monkeypatch.setattr(Group, "save", no_signal_save)

projects.set_current("activity-event")

assert not DatabaseParameter.select().count()
Expand Down Expand Up @@ -65,7 +71,13 @@ def test_database_parameter_revision_expected_format_create(num_revisions):


@bw2test
def test_database_parameter_revision_apply_create(num_revisions):
def test_database_parameter_revision_apply_create(num_revisions, monkeypatch):
def no_signal_save(self, *args, **kwargs):
kwargs["signal"] = False
return super(Group, self).save(*args, **kwargs)

monkeypatch.setattr(Group, "save", no_signal_save)

projects.set_current("activity-event")
DatabaseChooser("test-example").register()
assert projects.dataset.revision is None
Expand Down
Loading

0 comments on commit 0e66147

Please sign in to comment.