From: Karl O. Pinc Date: Tue, 19 Jan 2021 18:42:34 +0000 (-0600) Subject: Recover from db errors while building insert statements X-Git-Url: https://papio.biology.duke.edu/gitweb/?a=commitdiff_plain;h=a704a1efedaa4eeb545348b4889b3f499d454c0c;p=pgwui_bulk_upload Recover from db errors while building insert statements --- diff --git a/src/pgwui_bulk_upload/exceptions.py b/src/pgwui_bulk_upload/exceptions.py index d7ee256..08fad42 100644 --- a/src/pgwui_bulk_upload/exceptions.py +++ b/src/pgwui_bulk_upload/exceptions.py @@ -97,6 +97,16 @@ class CannotReadError(Error): f'The error is: {exp}') +class CannotRollbackError(Error): + def __init__(self, exp): + super().__init__( + 'Cannot roll back the current transaction', + 'The transaction has failed and must roll back before ' + 'the database can again be queried about relations and ' + 'their columns', + f'The error from psycopg2 is: ({exp})') + + class BadMapFileError(Error): pass diff --git a/src/pgwui_bulk_upload/views/bulk_upload.py b/src/pgwui_bulk_upload/views/bulk_upload.py index b540297..1043d7f 100644 --- a/src/pgwui_bulk_upload/views/bulk_upload.py +++ b/src/pgwui_bulk_upload/views/bulk_upload.py @@ -542,6 +542,7 @@ class BulkTableUploadHandler(BaseTableUploadHandler): quotecols = self.quote_columns() column_quoter = self.get_column_quoter(quotecols) + in_trans = True i_map = dict() errors = [] for fileinfo in self.data.filedata(): @@ -553,6 +554,20 @@ class BulkTableUploadHandler(BaseTableUploadHandler): map_description(fileinfo.filepath, fileinfo.relation), fileinfo.filepath, fileinfo.relation) errors.append(exp) + if in_trans: + # In order to continue to query the db after a db error + # the current transaction must be rolled back. + # Because we know we're going to abort, don't start a + # new transaction. + try: + self.cur.execute('ROLLBACK;') + except psycopg2.DatabaseError as exp: + err = ex.CannotRollbackError(exp) + err.color(map_description(fileinfo.filepath, + fileinfo.relation), + fileinfo.filepath, fileinfo.relation) + errors.append(err) + in_trans = False finally: # Limit number of open files, close the file handle until it # is time to read the file