diff --git a/spinedb_api/db_mapping_add_mixin.py b/spinedb_api/db_mapping_add_mixin.py index abd3b8db..a8447d14 100644 --- a/spinedb_api/db_mapping_add_mixin.py +++ b/spinedb_api/db_mapping_add_mixin.py @@ -17,7 +17,7 @@ from datetime import datetime from sqlalchemy import func, Table, Column, Integer, String, null, select from sqlalchemy.exc import DBAPIError -from .exception import SpineDBAPIError +from .exception import SpineDBAPIError, SpineIntegrityError from .helpers import get_relationship_entity_class_items, get_relationship_entity_items @@ -149,15 +149,23 @@ def add_items( list(SpineIntegrityError): found violations """ if readd: - self._readd_items(tablename, *items) - return items if return_items else {x["id"] for x in items}, [] + try: + self._readd_items(tablename, *items) + return items if return_items else {x["id"] for x in items}, [] + except SpineDBAPIError as e: + return set(), [e] + if check: checked_items, intgr_error_log = self.check_items( tablename, *items, for_update=False, strict=strict, cache=cache ) else: checked_items, intgr_error_log = list(items), [] - ids = self._add_items(tablename, *checked_items) + try: + ids = self._add_items(tablename, *checked_items) + except DBAPIError as e: + intgr_error_log.append(SpineIntegrityError(f"Fail to add items: {e.orig.args}")) + return set(), intgr_error_log if return_items: return checked_items, intgr_error_log if return_dups: diff --git a/spinedb_api/db_mapping_commit_mixin.py b/spinedb_api/db_mapping_commit_mixin.py index 025e186d..4bf39256 100644 --- a/spinedb_api/db_mapping_commit_mixin.py +++ b/spinedb_api/db_mapping_commit_mixin.py @@ -15,6 +15,7 @@ """ from datetime import datetime, timezone +import sqlalchemy.exc from .exception import SpineDBAPIError @@ -42,7 +43,10 @@ def _get_sqlite_lock(self): def _make_commit_id(self): if self._commit_id is None: if self.committing: - self._get_sqlite_lock() + try: + self._get_sqlite_lock() + except: + raise SpineDBAPIError("Committing failed due to the database being locked") self._commit_id = self._do_make_commit_id(self.connection) else: with self.engine.begin() as connection: @@ -66,7 +70,10 @@ def commit_session(self, comment): user = self.username date = datetime.now(timezone.utc) upd = commit.update().where(commit.c.id == self._make_commit_id()) - self._checked_execute(upd, dict(user=user, date=date, comment=comment)) + try: + self._checked_execute(upd, dict(user=user, date=date, comment=comment)) + except sqlalchemy.exc.DBAPIError as e: + raise SpineDBAPIError(f"Fail to commit: {e}") self.session.commit() self._commit_id = None if self._memory: diff --git a/spinedb_api/db_mapping_remove_mixin.py b/spinedb_api/db_mapping_remove_mixin.py index 5c2cf779..eac96a9b 100644 --- a/spinedb_api/db_mapping_remove_mixin.py +++ b/spinedb_api/db_mapping_remove_mixin.py @@ -77,14 +77,17 @@ def cascading_ids(self, cache=None, **kwargs): cascading_ids (dict): cascading ids keyed by table name """ if cache is None: - cache = self.make_cache( - set(kwargs), - include_descendants=True, - force_tablenames={"entity_metadata", "parameter_value_metadata"} - if any(x in kwargs for x in ("entity_metadata", "parameter_value_metadata", "metadata")) - else None, - keep_existing=True, - ) + try: + cache = self.make_cache( + set(kwargs), + include_descendants=True, + force_tablenames={"entity_metadata", "parameter_value_metadata"} + if any(x in kwargs for x in ("entity_metadata", "parameter_value_metadata", "metadata")) + else None, + keep_existing=True, + ) + except DBAPIError as e: + raise SpineDBAPIError(f"Fail to get cascading ids: {e.orig.args}") ids = {} self._merge(ids, self._object_class_cascading_ids(kwargs.get("object_class", set()), cache)) self._merge(ids, self._object_cascading_ids(kwargs.get("object", set()), cache)) diff --git a/spinedb_api/db_mapping_update_mixin.py b/spinedb_api/db_mapping_update_mixin.py index e2c4fd62..e36fb2f7 100644 --- a/spinedb_api/db_mapping_update_mixin.py +++ b/spinedb_api/db_mapping_update_mixin.py @@ -15,7 +15,7 @@ from collections import Counter from sqlalchemy.exc import DBAPIError from sqlalchemy.sql.expression import bindparam -from .exception import SpineDBAPIError +from .exception import SpineDBAPIError, SpineIntegrityError class DatabaseMappingUpdateMixin: @@ -78,7 +78,10 @@ def update_items(self, tablename, *items, check=True, strict=False, return_items ) else: checked_items, intgr_error_log = list(items), [] - updated_ids = self._update_items(tablename, *checked_items) + try: + updated_ids = self._update_items(tablename, *checked_items) + except SpineDBAPIError as e: + intgr_error_log.append(f"Fail to update items: {e}") if return_items: return checked_items, intgr_error_log return updated_ids, intgr_error_log