• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

LCA-ActivityBrowser / activity-browser / 7198760550

13 Dec 2023 05:18PM UTC coverage: 50.395% (+0.4%) from 50.044%
7198760550

push

github

web-flow
Better biosphere install/update handling (#1145)

* Delete .github/workflows/install-canary.yaml

* Add testing file

* Get available AB versions per AB version from online file

* Limit ecoinvent importer to versions compatible with this AB version

* Implement choosing of version during biosphere update

* Implement choosing of version during defaults import

* Resolve offline bug + better updating

* move compatible versions file

* implement local file fallback

* implement legacy biosphere imports for any chosen version AB is compatible with

* update test

* update test

* update test

* update test

* update test

* update test

* resolve calculation setup bug where activites are checked when biosphere was updated.

* minor updates to test documentation

* GH action script for commenting on issues when related milestone is closed.

* update bw2io requirement

* Update readme install instructions

* Update meta.yaml

* Update README.md

* Change requirement to brightway2 instead of bw2io

* Update README.md

* Increases the flexibility of the excel importer so it can also handle the parameter scenario files.

* Update README.md

How to install using Mamba

* Set up signals infrascructure

* Implement dialog

* Implement finding of suitable alternatives and proper management of failing that.

* Implement actual relinking

* Minor documentation improvements + store exchanges to remove instead of to keep.

* Minor documentation + code improvements

* Resolve #782 + improve documentation of `Contributions` class

* Minor documentation + code improvements

* Fix type hinting error

* Update README.md

* Update README.md

* Update README.md

* Updates to the functions get_relevant_flows and get_relevant_activities (#1069)

* Updates to the functions from de Koning (get_relevant_flows and get_relevant_activities), avoiding use of pandas apply and using python map function... (continued)

91 of 138 new or added lines in 8 files covered. (65.94%)

1 existing line in 1 file now uncovered.

6950 of 13791 relevant lines covered (50.4%)

0.5 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

48.7
/activity_browser/controllers/database.py
1
# -*- coding: utf-8 -*-
2
import brightway2 as bw
1✔
3
from bw2data.backends.peewee import sqlite3_lci_db
1✔
4
from bw2data.parameters import Group
1✔
5
from PySide2 import QtWidgets
1✔
6
from PySide2.QtCore import QObject, Slot, Qt
1✔
7

8
from ..bwutils import commontasks as bc
1✔
9
from ..bwutils.strategies import relink_exchanges_existing_db
1✔
10
from ..ui.widgets import (
1✔
11
    CopyDatabaseDialog, DatabaseLinkingDialog, DefaultBiosphereDialog,
12
    BiosphereUpdater, DatabaseLinkingResultsDialog, EcoinventVersionDialog
13
)
14
from ..ui.wizards.db_export_wizard import DatabaseExportWizard
1✔
15
from ..ui.wizards.db_import_wizard import DatabaseImportWizard
1✔
16
from ..settings import project_settings
1✔
17
from ..signals import signals
1✔
18
from .project import ProjectController
1✔
19
from ..info import __ei_versions__
1✔
20
from ..utils import sort_semantic_versions
1✔
21

22
import logging
1✔
23
from activity_browser.logger import ABHandler
1✔
24

25
logger = logging.getLogger('ab_logs')
1✔
26
log = ABHandler.setup_with_logger(logger, __name__)
1✔
27

28

29

30
class DatabaseController(QObject):
1✔
31

32
    def __init__(self, parent=None):
1✔
33
        super().__init__(parent)
1✔
34
        self.window = parent
1✔
35

36
        signals.import_database.connect(self.import_database_wizard)
1✔
37
        signals.export_database.connect(self.export_database_wizard)
1✔
38
        signals.update_biosphere.connect(self.update_biosphere)
1✔
39
        signals.add_database.connect(self.add_database)
1✔
40
        signals.delete_database.connect(self.delete_database)
1✔
41
        signals.copy_database.connect(self.copy_database)
1✔
42
        signals.install_default_data.connect(self.install_default_data)
1✔
43
        signals.relink_database.connect(self.relink_database)
1✔
44

45
        signals.project_selected.connect(self.ensure_sqlite_indices)
1✔
46

47
    @Slot(name="openImportWizard")
1✔
48
    def import_database_wizard(self) -> None:
1✔
49
        """Start the database import wizard."""
50
        wizard = DatabaseImportWizard(self.window)
×
51
        wizard.show()
×
52

53
    @Slot(name="openExportWizard")
1✔
54
    def export_database_wizard(self) -> None:
1✔
55
        wizard = DatabaseExportWizard(self.window)
×
56
        wizard.show()
×
57

58
    @Slot(name="fixBrokenIndexes")
1✔
59
    def ensure_sqlite_indices(self):
1✔
60
        """
61
        - fix for https://github.com/LCA-ActivityBrowser/activity-browser/issues/189
62
        - also see bw2data issue: https://bitbucket.org/cmutel/brightway2-data/issues/60/massive-sqlite-query-performance-decrease
63
        @LegacyCode?
64
        """
65
        if bw.databases and not sqlite3_lci_db._database.get_indexes('activitydataset'):
1✔
66
            log.info("creating missing sqlite indices")
×
67
            bw.Database(list(bw.databases)[-1])._add_indices()
×
68

69
    @Slot(name="bw2Setup")
1✔
70
    def install_default_data(self) -> None:
1✔
71

72
        # let user choose version
73
        version_dialog = EcoinventVersionDialog(self.window)
1✔
74
        if version_dialog.exec_() != EcoinventVersionDialog.Accepted: return
1✔
75
        version = version_dialog.options.currentText()
1✔
76

77
        dialog = DefaultBiosphereDialog(version[:3], self.window)  # only read Major/Minor part of version
1✔
78
        dialog.show()
1✔
79

80
    @Slot(name="updateBiosphereDialog")
1✔
81
    def update_biosphere(self) -> None:
1✔
82
        """ Open a popup with progression bar and run through the different
83
        functions for adding ecoinvent biosphere flows.
84
        """
85
        # warn user of consequences of updating
NEW
86
        warn_dialog = QtWidgets.QMessageBox.question(
×
87
            self.window, "Update biosphere3?",
88
            'Newer versions of the biosphere database may not\n'
89
            'always be compatible with older ecoinvent versions.\n'
90
            '\nUpdating the biosphere3 database cannot be undone!\n',
91
            QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Abort,
92
            QtWidgets.QMessageBox.Abort
93
        )
NEW
94
        if warn_dialog is not QtWidgets.QMessageBox.Ok: return
×
95

96
        # let user choose version
NEW
97
        version_dialog = EcoinventVersionDialog(self.window)
×
NEW
98
        if version_dialog.exec_() != EcoinventVersionDialog.Accepted: return
×
NEW
99
        version = version_dialog.options.currentText()
×
100

101
        # reduce biosphere update list up to the selected version
NEW
102
        sorted_versions = sort_semantic_versions(__ei_versions__, highest_to_lowest=False)
×
NEW
103
        ei_versions = sorted_versions[:sorted_versions.index(version) + 1]
×
104

105
        # show updating dialog
NEW
106
        dialog = BiosphereUpdater(ei_versions, self.window)
×
NEW
107
        dialog.show()
×
108

109
    @Slot(name="addDatabase")
1✔
110
    def add_database(self):
1✔
111
        name, ok = QtWidgets.QInputDialog.getText(
×
112
            self.window,
113
            "Create new database",
114
            "Name of new database:" + " " * 25
115
        )
116

117
        if ok and name:
×
118
            if name not in bw.databases:
×
119
                bw.Database(name).register()
×
120
                project_settings.add_db(name, False)
×
121
                signals.databases_changed.emit()
×
122
                signals.database_selected.emit(name)
×
123
            else:
124
                QtWidgets.QMessageBox.information(
×
125
                    self.window, "Not possible", "A database with this name already exists."
126
                )
127

128
    @Slot(str, QObject, name="copyDatabaseAction")
1✔
129
    def copy_database(self, name: str) -> None:
1✔
130
        new_name, ok = QtWidgets.QInputDialog.getText(
×
131
            self.window,
132
            "Copy {}".format(name),
133
            "Name of new database:" + " " * 25)
134
        if ok and new_name:
×
135
            try:
×
136
                # Attaching the created wizard to the class avoids the copying
137
                # thread being prematurely destroyed.
138
                copy_progress = CopyDatabaseDialog(self.window)
×
139
                copy_progress.show()
×
140
                copy_progress.begin_copy(name, new_name)
×
141
                project_settings.add_db(new_name, project_settings.db_is_readonly(name))
×
142
            except ValueError as e:
×
143
                QtWidgets.QMessageBox.information(self.window, "Not possible", str(e))
×
144

145
    @Slot(str, name="deleteDatabase")
1✔
146
    def delete_database(self, name: str) -> None:
1✔
147
        ok = QtWidgets.QMessageBox.question(
×
148
            self.window,
149
            "Delete database?",
150
            ("Are you sure you want to delete database '{}'? It has {} activity datasets").format(
151
                name, bc.count_database_records(name))
152
        )
153
        if ok == QtWidgets.QMessageBox.Yes:
×
154
            project_settings.remove_db(name)
×
155
            del bw.databases[name]
×
156
            Group.delete().where(Group.name == name).execute()
×
157
            ProjectController.change_project(bw.projects.current, reload=True)
×
158
            signals.delete_database_confirmed.emit(name)
×
159

160
    @Slot(str, name="relinkDatabase")
1✔
161
    def relink_database(self, db_name: str) -> None:
1✔
162
        """Relink technosphere exchanges within the given database."""
163
        db = bw.Database(db_name)
×
164
        depends = db.find_dependents()
×
165
        options = [(depend, bw.databases.list) for depend in depends]
×
166
        dialog = DatabaseLinkingDialog.relink_sqlite(db_name, options, self.window)
×
167
        relinking_results = dict()
×
168
        if dialog.exec_() == DatabaseLinkingDialog.Accepted:
×
169
            # Now, start relinking.
170
            QtWidgets.QApplication.setOverrideCursor(Qt.WaitCursor)
×
171
            for old, new in dialog.relink.items():
×
172
                other = bw.Database(new)
×
173
                failed, succeeded, examples = relink_exchanges_existing_db(db, old, other)
×
174
                relinking_results[f"{old} --> {other.name}"] = (failed, succeeded)
×
175
            QtWidgets.QApplication.restoreOverrideCursor()
×
176
            if failed > 0:
×
177
                QtWidgets.QApplication.restoreOverrideCursor()
×
178
                relinking_dialog = DatabaseLinkingResultsDialog.present_relinking_results(self.window, relinking_results, examples)
×
179
                relinking_dialog.exec_()
×
180
                activity = relinking_dialog.open_activity()
×
181
            QtWidgets.QApplication.restoreOverrideCursor()
×
182
            signals.database_changed.emit(db_name)
×
183
            signals.databases_changed.emit()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc