# Buggy code
def precreate_dataset_collection(
    self,
    structure,
    allow_unitialized_element=True,
    completed_collection=None,
    implicit_output_name=None,
):
    has_structure = not structure.is_leaf and structure.children_known
    if not has_structure and allow_unitialized_element:
        dataset_collection = model.DatasetCollectionElement.UNINITIALIZED_ELEMENT
    elif not has_structure:
        collection_type_description = structure.collection_type_description
        dataset_collection = model.DatasetCollection(populated=False)
        dataset_collection.collection_type = collection_type_description.collection_type
    else:
        collection_type_description = structure.collection_type_description
        dataset_collection = model.DatasetCollection(populated=False)
        dataset_collection.collection_type = collection_type_description.collection_type
        elements = []
        for index, (identifier, substructure) in enumerate(structure.children):
            # TODO: Open question - populate these now or later?
            element = None
            if completed_collection and implicit_output_name:
                job = completed_collection[index]
                if job:
                    it = (
                        jtiodca.dataset_collection
                        for jtiodca in job.output_dataset_collections
                        if jtiodca.name == implicit_output_name
                    )
                    element = next(it, None)
            if element is None:
                if substructure.is_leaf:
                    element = model.DatasetCollectionElement.UNINITIALIZED_ELEMENT
                else:
                    element = self.precreate_dataset_collection(
                        substructure,
                        allow_unitialized_element=allow_unitialized_element,
                    )

            element = model.DatasetCollectionElement(
                element=element,
                element_identifier=identifier,
                element_index=index,
            )
            elements.append(element)
        dataset_collection.elements = elements
        dataset_collection.element_count = len(elements)

    return dataset_collection


# Traceback (sqlalchemy.exc.IntegrityError)
Nov 01 14:58:58 sn04.bi.uni-freiburg.de python[1827028]: galaxy.jobs DEBUG 2020-11-01 14:58:58,991 (12059080) Working directory for job is: /data/dnb03/galaxy_db/job_working_directory/012/059/12059080
Nov 01 14:58:58 sn04.bi.uni-freiburg.de python[1847375]: galaxy.jobs DEBUG 2020-11-01 14:58:58,998 (12059086) Working directory for job is: /data/dnb03/galaxy_db/job_working_directory/012/059/12059086
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1847375]: galaxy.objectstore DEBUG 2020-11-01 14:58:59,011 Using preferred backend 'files10' for creation of Dataset 27240484
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: galaxy.job_execution.output_collect ERROR 2020-11-01 14:58:59,036 Problem gathering output collection.
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: Traceback (most recent call last):
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/venv/lib64/python3.6/site-packages/sqlalchemy/engine/base.py", line 1284, in _execute_context
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: cursor, statement, parameters, context
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/venv/lib64/python3.6/site-packages/sqlalchemy/engine/default.py", line 590, in do_execute
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: cursor.execute(statement, parameters)
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: psycopg2.errors.NotNullViolation: null value in column "dataset_collection_id" violates not-null constraint
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: DETAIL:  Failing row contains (13330967, null, 30637828, null, null, 0, ERR4597396__single).
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: The above exception was the direct cause of the following exception:
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: Traceback (most recent call last):
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/server/lib/galaxy/job_execution/output_collect.py", line 156, in collect_dynamic_outputs
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: final_job_state=job_context.final_job_state,
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/server/lib/galaxy/model/store/discover.py", line 286, in populate_collection_elements
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: self.flush()
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/server/lib/galaxy/job_execution/output_collect.py", line 214, in flush
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: self.sa_session.flush()
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/venv/lib64/python3.6/site-packages/sqlalchemy/orm/scoping.py", line 163, in do
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: return getattr(self.registry(), name)(*args, **kwargs)
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/venv/lib64/python3.6/site-packages/sqlalchemy/orm/session.py", line 2523, in flush
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: self._flush(objects)
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/venv/lib64/python3.6/site-packages/sqlalchemy/orm/session.py", line 2664, in _flush
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: transaction.rollback(_capture_exception=True)
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/venv/lib64/python3.6/site-packages/sqlalchemy/util/langhelpers.py", line 69, in __exit__
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: exc_value, with_traceback=exc_tb,
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/venv/lib64/python3.6/site-packages/sqlalchemy/util/compat.py", line 178, in raise_
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: raise exception
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/venv/lib64/python3.6/site-packages/sqlalchemy/orm/session.py", line 2624, in _flush
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: flush_context.execute()
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/venv/lib64/python3.6/site-packages/sqlalchemy/orm/unitofwork.py", line 422, in execute
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: rec.execute(self)
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/venv/lib64/python3.6/site-packages/sqlalchemy/orm/unitofwork.py", line 589, in execute
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: uow,
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/venv/lib64/python3.6/site-packages/sqlalchemy/orm/persistence.py", line 236, in save_obj
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: update,
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/venv/lib64/python3.6/site-packages/sqlalchemy/orm/persistence.py", line 995, in _emit_update_statements
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: statement, multiparams
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/venv/lib64/python3.6/site-packages/sqlalchemy/engine/base.py", line 1020, in execute
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: return meth(self, multiparams, params)
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/venv/lib64/python3.6/site-packages/sqlalchemy/sql/elements.py", line 298, in _execute_on_connection
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: return connection._execute_clauseelement(self, multiparams, params)
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/venv/lib64/python3.6/site-packages/sqlalchemy/engine/base.py", line 1139, in _execute_clauseelement
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: distilled_params,
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/venv/lib64/python3.6/site-packages/sqlalchemy/engine/base.py", line 1324, in _execute_context
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: e, statement, parameters, cursor, context
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/venv/lib64/python3.6/site-packages/sqlalchemy/engine/base.py", line 1518, in _handle_dbapi_exception
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: sqlalchemy_exception, with_traceback=exc_info[2], from_=e
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/venv/lib64/python3.6/site-packages/sqlalchemy/util/compat.py", line 178, in raise_
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: raise exception
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/venv/lib64/python3.6/site-packages/sqlalchemy/engine/base.py", line 1284, in _execute_context
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: cursor, statement, parameters, context
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: File "/opt/galaxy/venv/lib64/python3.6/site-packages/sqlalchemy/engine/default.py", line 590, in do_execute
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: cursor.execute(statement, parameters)
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: sqlalchemy.exc.IntegrityError: (psycopg2.errors.NotNullViolation) null value in column "dataset_collection_id" violates not-null constraint
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: DETAIL:  Failing row contains (13330967, null, 30637828, null, null, 0, ERR4597396__single).
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: [SQL: UPDATE dataset_collection_element SET dataset_collection_id=%(dataset_collection_id)s WHERE dataset_collection_element.id = %(dataset_collection_element_id)s]
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: [parameters: {'dataset_collection_id': None, 'dataset_collection_element_id': 13330967}]
Nov 01 14:58:59 sn04.bi.uni-freiburg.de python[1819184]: (Background on this error at: http://sqlalche.me/e/gkpj)

# Fixed code
def precreate_dataset_collection(
    self,
    structure,
    allow_unitialized_element=True,
    completed_collection=None,
    implicit_output_name=None,
):
    has_structure = not structure.is_leaf and structure.children_known
    if not has_structure and allow_unitialized_element:
        dataset_collection = model.DatasetCollectionElement.UNINITIALIZED_ELEMENT
    elif not has_structure:
        collection_type_description = structure.collection_type_description
        dataset_collection = model.DatasetCollection(populated=False)
        dataset_collection.collection_type = collection_type_description.collection_type
    else:
        collection_type_description = structure.collection_type_description
        dataset_collection = model.DatasetCollection(populated=False)
        dataset_collection.collection_type = collection_type_description.collection_type
        elements = []
        for index, (identifier, substructure) in enumerate(structure.children):
            # TODO: Open question - populate these now or later?
            element = None
            if completed_collection and implicit_output_name:
                job = completed_collection[index]
                if job:
                    it = (
                        jtiodca.dataset_collection
                        for jtiodca in job.output_dataset_collections
                        if jtiodca.name == implicit_output_name
                    )
                    element = next(it, None)
            if element is None:
                if substructure.is_leaf:
                    element = model.DatasetCollectionElement.UNINITIALIZED_ELEMENT
                else:
                    element = self.precreate_dataset_collection(
                        substructure,
                        allow_unitialized_element=allow_unitialized_element,
                    )

            element = model.DatasetCollectionElement(
                collection=dataset_collection,
                element=element,
                element_identifier=identifier,
                element_index=index,
            )
            elements.append(element)
        dataset_collection.element_count = len(elements)

    return dataset_collection