pynbody / tangos

The Agile Numerical Galaxy Organisation System
BSD 3-Clause "New" or "Revised" License
18 stars 13 forks source link

Tangos seems broken with SQLAlchemy > 2.0 #213

Closed Martin-Rey closed 1 year ago

Martin-Rey commented 1 year ago

Hi all,

I am posting this here as documentation, it's unclear to me whether it requires active fixing or is the result of active developments in SQL Alchemy.

The default pip install sqlalchemy will now grab the 2.0.X betas of this package (https://docs.sqlalchemy.org/en/20/changelog/whatsnew_20.html), which breaks the tangos tests for me (see below for errors).

Reverting to pip install sqlalchemy=1.4.44 fixes the tests again. If changes in sqlalchemy > 2.0 introduce long-term incompatibilities, we should consider specifying a maximum version, or upgrade the failing below tests.

Martin

============================================================================== test session starts ===============================================================================
platform darwin -- Python 3.9.6, pytest-7.2.0, pluggy-1.0.0
rootdir: /Users/mrey/Documents/tangos
plugins: anyio-3.6.2
collected 253 items                                                                                                                                                              

test_ahf_trees.py ..                                                                                                                                                       [  0%]
test_bh_reader.py .                                                                                                                                                        [  1%]
test_big_integer_halos.py .                                                                                                                                                [  1%]
test_blocking_session.py ..                                                                                                                                                [  2%]
test_check_deleted.py ...                                                                                                                                                  [  3%]
test_consistent_collection.py .....                                                                                                                                        [  5%]
test_consistent_trees.py ..                                                                                                                                                [  6%]
test_data_attribute_mapper.py ...............                                                                                                                              [ 12%]
test_db_writer.py .........                                                                                                                                                [ 15%]
test_dict_caching.py .                                                                                                                                                     [ 16%]
test_difficult_merger_scenario.py .....                                                                                                                                    [ 18%]
test_halo_setitem.py ....                                                                                                                                                  [ 19%]
test_histogram_property.py ........                                                                                                                                        [ 22%]
test_hop_strategy.py ..............................                                                                                                                        [ 34%]
test_import.py .                                                                                                                                                           [ 35%]
test_import_dependencies.py .                                                                                                                                              [ 35%]
test_linking.py ....                                                                                                                                                       [ 37%]
test_live_calculation.py .....................F....                                                                                                                        [ 47%]
test_live_calculation_link_syntax.py ............                                                                                                                          [ 52%]
test_merger_tree.py ...                                                                                                                                                    [ 53%]
test_object_specialisms.py ...                                                                                                                                             [ 54%]
test_old_database_update.py .                                                                                                                                              [ 54%]
test_parallel_tasks.py .......                                                                                                                                             [ 57%]
test_property_class_mapping.py ......                                                                                                                                      [ 60%]
test_property_deleter.py .....                                                                                                                                             [ 62%]
test_property_gathering.py ......FFF.........FF...                                                                                                                         [ 71%]
test_proxy_object.py .....                                                                                                                                                 [ 73%]
test_pynbody_server.py .........                                                                                                                                           [ 76%]
test_remove_duplicate.py F                                                                                                                                                 [ 77%]
test_simulation_adder.py ...........                                                                                                                                       [ 81%]
test_simulation_outputs.py ...................                                                                                                                             [ 88%]
test_stat_files.py ........                                                                                                                                                [ 92%]
test_timing.py .                                                                                                                                                           [ 92%]
test_tracking.py ..                                                                                                                                                        [ 93%]
test_web.py .............                                                                                                                                                  [ 98%]
test_yt.py ....                                                                                                                                                            [100%]

==================================================================================== FAILURES ====================================================================================
____________________________________________________________________ test_liveproperty_requiring_redirection _____________________________________________________________________

    def test_liveproperty_requiring_redirection():
        h = tangos.get_halo("sim/ts1/1")
        assert h.calculate("first_BHs_BH_mass()") == h['BH'][0]['BH_mass']
>       cascade_version = h.calculate_for_descendants("first_BHs_BH_mass()")

test_live_calculation.py:259: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../tangos/core/halo.py:379: in calculate_for_descendants
    results = query.all()
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/query.py:2590: in all
    return self._iter().all()  # type: ignore
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/query.py:2730: in _iter
    result: Union[ScalarResult[_T], Result[_T]] = self.session.execute(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/session.py:2081: in execute
    return self._execute_internal(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/session.py:1976: in _execute_internal
    result: Result[Any] = compile_state_cls.orm_execute_statement(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/context.py:250: in orm_execute_statement
    result = conn.execute(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/engine/base.py:1414: in execute
    return meth(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/elements.py:487: in _execute_on_connection
    return connection._execute_clauseelement(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/engine/base.py:1630: in _execute_clauseelement
    compiled_sql, extracted_params, cache_hit = elem._compile_w_cache(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/elements.py:652: in _compile_w_cache
    compiled_sql = self._compiler(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/elements.py:288: in _compiler
    return dialect.statement_compiler(dialect, self, **kw)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:1075: in __init__
    Compiled.__init__(self, dialect, statement, **kwargs)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:639: in __init__
    self.string = self.process(self.statement, **compile_kwargs)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:671: in process
    return obj._compiler_dispatch(self, **kwargs)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/visitors.py:143: in _compiler_dispatch
    return meth(self, **kw)  # type: ignore  # noqa: E501
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:3949: in visit_select
    compile_state = select_stmt._compile_state_factory(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/base.py:641: in create_for_statement
    return klass.create_for_statement(statement, compiler, **kw)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/context.py:1012: in create_for_statement
    opt.process_compile_state(self)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:929: in process_compile_state
    self._process(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:1151: in _process
    loader.process_compile_state(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:1699: in process_compile_state
    keys = self._prepare_for_compile_state(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:2070: in _prepare_for_compile_state
    self._raise_for_no_match(parent_loader, mapper_entities)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.orm.strategy_options._AttributeStrategyLoad object at 0x1737aeee0>, parent_loader = <sqlalchemy.orm.strategy_options.Load object at 0x17371fd80>
mapper_entities = [<sqlalchemy.orm.context._MapperEntity object at 0x173921970>]

    def _raise_for_no_match(self, parent_loader, mapper_entities):
        path = parent_loader.path

        found_entities = False
        for ent in mapper_entities:
            ezero = ent.entity_zero
            if ezero:
                found_entities = True
                break

        if not found_entities:
            raise sa_exc.ArgumentError(
                "Query has only expression-based entities; "
                f"attribute loader options for {path[0]} can't "
                "be applied here."
            )
        else:
>           raise sa_exc.ArgumentError(
                f"Mapped class {path[0]} does not apply to any of the "
                f"root entities in this query, e.g. "
                f"""{
                    ", ".join(str(x.entity_zero)
                    for x in mapper_entities if x.entity_zero
                )}. Please """
                "specify the full path "
                "from one of the root entities to the target "
                "attribute. "
            )
E           sqlalchemy.exc.ArgumentError: Mapped class aliased(HaloLink) does not apply to any of the root entities in this query, e.g. Mapper[SimulationObjectBase(halos)]. Please specify the full path from one of the root entities to the target attribute.

../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:1618: ArgumentError
______________________________________________________________________ test_gather_linked_property_with_fn _______________________________________________________________________

    def test_gather_linked_property_with_fn():
>       BH_mass, Mv = tangos.get_timestep("sim/ts1").calculate_all('my_BH().hole_mass', "Mvir")

test_property_gathering.py:146: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../tangos/core/timestep.py:160: in calculate_all
    sql_query_results = query.all()
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/query.py:2590: in all
    return self._iter().all()  # type: ignore
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/query.py:2730: in _iter
    result: Union[ScalarResult[_T], Result[_T]] = self.session.execute(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/session.py:2081: in execute
    return self._execute_internal(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/session.py:1976: in _execute_internal
    result: Result[Any] = compile_state_cls.orm_execute_statement(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/context.py:250: in orm_execute_statement
    result = conn.execute(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/engine/base.py:1414: in execute
    return meth(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/elements.py:487: in _execute_on_connection
    return connection._execute_clauseelement(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/engine/base.py:1630: in _execute_clauseelement
    compiled_sql, extracted_params, cache_hit = elem._compile_w_cache(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/elements.py:652: in _compile_w_cache
    compiled_sql = self._compiler(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/elements.py:288: in _compiler
    return dialect.statement_compiler(dialect, self, **kw)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:1075: in __init__
    Compiled.__init__(self, dialect, statement, **kwargs)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:639: in __init__
    self.string = self.process(self.statement, **compile_kwargs)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:671: in process
    return obj._compiler_dispatch(self, **kwargs)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/visitors.py:143: in _compiler_dispatch
    return meth(self, **kw)  # type: ignore  # noqa: E501
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:3949: in visit_select
    compile_state = select_stmt._compile_state_factory(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/base.py:641: in create_for_statement
    return klass.create_for_statement(statement, compiler, **kw)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/context.py:1012: in create_for_statement
    opt.process_compile_state(self)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:929: in process_compile_state
    self._process(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:1151: in _process
    loader.process_compile_state(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:1699: in process_compile_state
    keys = self._prepare_for_compile_state(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:2070: in _prepare_for_compile_state
    self._raise_for_no_match(parent_loader, mapper_entities)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.orm.strategy_options._AttributeStrategyLoad object at 0x175a77460>, parent_loader = <sqlalchemy.orm.strategy_options.Load object at 0x175a6f940>
mapper_entities = [<sqlalchemy.orm.context._MapperEntity object at 0x175b8f270>]

    def _raise_for_no_match(self, parent_loader, mapper_entities):
        path = parent_loader.path

        found_entities = False
        for ent in mapper_entities:
            ezero = ent.entity_zero
            if ezero:
                found_entities = True
                break

        if not found_entities:
            raise sa_exc.ArgumentError(
                "Query has only expression-based entities; "
                f"attribute loader options for {path[0]} can't "
                "be applied here."
            )
        else:
>           raise sa_exc.ArgumentError(
                f"Mapped class {path[0]} does not apply to any of the "
                f"root entities in this query, e.g. "
                f"""{
                    ", ".join(str(x.entity_zero)
                    for x in mapper_entities if x.entity_zero
                )}. Please """
                "specify the full path "
                "from one of the root entities to the target "
                "attribute. "
            )
E           sqlalchemy.exc.ArgumentError: Mapped class aliased(HaloLink) does not apply to any of the root entities in this query, e.g. Mapper[SimulationObjectBase(halos)]. Please specify the full path from one of the root entities to the target attribute.

../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:1618: ArgumentError
____________________________________________________________________________ test_path_factorisation _____________________________________________________________________________

    def test_path_factorisation():

        _TestPathChoice.num_calls = 0

        #desc = lc.MultiCalculationDescription(
        #    'my_BH("hole_spin").hole_mass',
        #    'my_BH("hole_spin").hole_spin',
        #    'Mvir')

>       BH_mass, BH_spin, Mv = tangos.get_timestep("sim/ts1").calculate_all('my_BH("hole_spin").(hole_mass, hole_spin)', 'Mvir')

test_property_gathering.py:163: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../tangos/core/timestep.py:160: in calculate_all
    sql_query_results = query.all()
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/query.py:2590: in all
    return self._iter().all()  # type: ignore
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/query.py:2730: in _iter
    result: Union[ScalarResult[_T], Result[_T]] = self.session.execute(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/session.py:2081: in execute
    return self._execute_internal(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/session.py:1976: in _execute_internal
    result: Result[Any] = compile_state_cls.orm_execute_statement(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/context.py:250: in orm_execute_statement
    result = conn.execute(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/engine/base.py:1414: in execute
    return meth(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/elements.py:487: in _execute_on_connection
    return connection._execute_clauseelement(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/engine/base.py:1630: in _execute_clauseelement
    compiled_sql, extracted_params, cache_hit = elem._compile_w_cache(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/elements.py:652: in _compile_w_cache
    compiled_sql = self._compiler(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/elements.py:288: in _compiler
    return dialect.statement_compiler(dialect, self, **kw)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:1075: in __init__
    Compiled.__init__(self, dialect, statement, **kwargs)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:639: in __init__
    self.string = self.process(self.statement, **compile_kwargs)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:671: in process
    return obj._compiler_dispatch(self, **kwargs)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/visitors.py:143: in _compiler_dispatch
    return meth(self, **kw)  # type: ignore  # noqa: E501
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:3949: in visit_select
    compile_state = select_stmt._compile_state_factory(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/base.py:641: in create_for_statement
    return klass.create_for_statement(statement, compiler, **kw)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/context.py:1012: in create_for_statement
    opt.process_compile_state(self)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:929: in process_compile_state
    self._process(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:1151: in _process
    loader.process_compile_state(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:1699: in process_compile_state
    keys = self._prepare_for_compile_state(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:2070: in _prepare_for_compile_state
    self._raise_for_no_match(parent_loader, mapper_entities)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.orm.strategy_options._AttributeStrategyLoad object at 0x1759de2e0>, parent_loader = <sqlalchemy.orm.strategy_options.Load object at 0x1759fa640>
mapper_entities = [<sqlalchemy.orm.context._MapperEntity object at 0x175a4bf20>]

    def _raise_for_no_match(self, parent_loader, mapper_entities):
        path = parent_loader.path

        found_entities = False
        for ent in mapper_entities:
            ezero = ent.entity_zero
            if ezero:
                found_entities = True
                break

        if not found_entities:
            raise sa_exc.ArgumentError(
                "Query has only expression-based entities; "
                f"attribute loader options for {path[0]} can't "
                "be applied here."
            )
        else:
>           raise sa_exc.ArgumentError(
                f"Mapped class {path[0]} does not apply to any of the "
                f"root entities in this query, e.g. "
                f"""{
                    ", ".join(str(x.entity_zero)
                    for x in mapper_entities if x.entity_zero
                )}. Please """
                "specify the full path "
                "from one of the root entities to the target "
                "attribute. "
            )
E           sqlalchemy.exc.ArgumentError: Mapped class aliased(HaloLink) does not apply to any of the root entities in this query, e.g. Mapper[SimulationObjectBase(halos)]. Please specify the full path from one of the root entities to the target attribute.

../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:1618: ArgumentError
_______________________________________________________________________________ test_single_quotes _______________________________________________________________________________

    def test_single_quotes():
>       BH_mass, Mv = tangos.get_timestep("sim/ts1").calculate_all("my_BH('hole_spin').hole_mass", "Mvir")

test_property_gathering.py:176: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../tangos/core/timestep.py:160: in calculate_all
    sql_query_results = query.all()
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/query.py:2590: in all
    return self._iter().all()  # type: ignore
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/query.py:2730: in _iter
    result: Union[ScalarResult[_T], Result[_T]] = self.session.execute(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/session.py:2081: in execute
    return self._execute_internal(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/session.py:1976: in _execute_internal
    result: Result[Any] = compile_state_cls.orm_execute_statement(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/context.py:250: in orm_execute_statement
    result = conn.execute(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/engine/base.py:1414: in execute
    return meth(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/elements.py:487: in _execute_on_connection
    return connection._execute_clauseelement(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/engine/base.py:1630: in _execute_clauseelement
    compiled_sql, extracted_params, cache_hit = elem._compile_w_cache(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/elements.py:652: in _compile_w_cache
    compiled_sql = self._compiler(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/elements.py:288: in _compiler
    return dialect.statement_compiler(dialect, self, **kw)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:1075: in __init__
    Compiled.__init__(self, dialect, statement, **kwargs)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:639: in __init__
    self.string = self.process(self.statement, **compile_kwargs)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:671: in process
    return obj._compiler_dispatch(self, **kwargs)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/visitors.py:143: in _compiler_dispatch
    return meth(self, **kw)  # type: ignore  # noqa: E501
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:3949: in visit_select
    compile_state = select_stmt._compile_state_factory(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/base.py:641: in create_for_statement
    return klass.create_for_statement(statement, compiler, **kw)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/context.py:1012: in create_for_statement
    opt.process_compile_state(self)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:929: in process_compile_state
    self._process(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:1151: in _process
    loader.process_compile_state(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:1699: in process_compile_state
    keys = self._prepare_for_compile_state(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:2070: in _prepare_for_compile_state
    self._raise_for_no_match(parent_loader, mapper_entities)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.orm.strategy_options._AttributeStrategyLoad object at 0x175b67ca0>, parent_loader = <sqlalchemy.orm.strategy_options.Load object at 0x175c8ddc0>
mapper_entities = [<sqlalchemy.orm.context._MapperEntity object at 0x175adb120>]

    def _raise_for_no_match(self, parent_loader, mapper_entities):
        path = parent_loader.path

        found_entities = False
        for ent in mapper_entities:
            ezero = ent.entity_zero
            if ezero:
                found_entities = True
                break

        if not found_entities:
            raise sa_exc.ArgumentError(
                "Query has only expression-based entities; "
                f"attribute loader options for {path[0]} can't "
                "be applied here."
            )
        else:
>           raise sa_exc.ArgumentError(
                f"Mapped class {path[0]} does not apply to any of the "
                f"root entities in this query, e.g. "
                f"""{
                    ", ".join(str(x.entity_zero)
                    for x in mapper_entities if x.entity_zero
                )}. Please """
                "specify the full path "
                "from one of the root entities to the target "
                "attribute. "
            )
E           sqlalchemy.exc.ArgumentError: Mapped class aliased(HaloLink) does not apply to any of the root entities in this query, e.g. Mapper[SimulationObjectBase(halos)]. Please specify the full path from one of the root entities to the target attribute.

../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:1618: ArgumentError
__________________________________________________________________ test_redirection_cascade_closes_connections ___________________________________________________________________

    def test_redirection_cascade_closes_connections():
        h = tangos.get_halo("sim/ts3/1")
        with db.testing.assert_connections_all_closed():
>           h.calculate_for_progenitors("my_BH('hole_spin').hole_mass")

test_property_gathering.py:239: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../tangos/core/halo.py:391: in calculate_for_progenitors
    return self.calculate_for_descendants(*plist, **kwargs)
../tangos/core/halo.py:379: in calculate_for_descendants
    results = query.all()
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/query.py:2590: in all
    return self._iter().all()  # type: ignore
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/query.py:2730: in _iter
    result: Union[ScalarResult[_T], Result[_T]] = self.session.execute(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/session.py:2081: in execute
    return self._execute_internal(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/session.py:1976: in _execute_internal
    result: Result[Any] = compile_state_cls.orm_execute_statement(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/context.py:250: in orm_execute_statement
    result = conn.execute(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/engine/base.py:1414: in execute
    return meth(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/elements.py:487: in _execute_on_connection
    return connection._execute_clauseelement(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/engine/base.py:1630: in _execute_clauseelement
    compiled_sql, extracted_params, cache_hit = elem._compile_w_cache(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/elements.py:652: in _compile_w_cache
    compiled_sql = self._compiler(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/elements.py:288: in _compiler
    return dialect.statement_compiler(dialect, self, **kw)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:1075: in __init__
    Compiled.__init__(self, dialect, statement, **kwargs)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:639: in __init__
    self.string = self.process(self.statement, **compile_kwargs)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:671: in process
    return obj._compiler_dispatch(self, **kwargs)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/visitors.py:143: in _compiler_dispatch
    return meth(self, **kw)  # type: ignore  # noqa: E501
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:3949: in visit_select
    compile_state = select_stmt._compile_state_factory(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/base.py:641: in create_for_statement
    return klass.create_for_statement(statement, compiler, **kw)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/context.py:1012: in create_for_statement
    opt.process_compile_state(self)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:929: in process_compile_state
    self._process(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:1151: in _process
    loader.process_compile_state(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:1699: in process_compile_state
    keys = self._prepare_for_compile_state(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:2070: in _prepare_for_compile_state
    self._raise_for_no_match(parent_loader, mapper_entities)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.orm.strategy_options._AttributeStrategyLoad object at 0x175bd2520>, parent_loader = <sqlalchemy.orm.strategy_options.Load object at 0x1759bc580>
mapper_entities = [<sqlalchemy.orm.context._MapperEntity object at 0x175ba1900>]

    def _raise_for_no_match(self, parent_loader, mapper_entities):
        path = parent_loader.path

        found_entities = False
        for ent in mapper_entities:
            ezero = ent.entity_zero
            if ezero:
                found_entities = True
                break

        if not found_entities:
            raise sa_exc.ArgumentError(
                "Query has only expression-based entities; "
                f"attribute loader options for {path[0]} can't "
                "be applied here."
            )
        else:
>           raise sa_exc.ArgumentError(
                f"Mapped class {path[0]} does not apply to any of the "
                f"root entities in this query, e.g. "
                f"""{
                    ", ".join(str(x.entity_zero)
                    for x in mapper_entities if x.entity_zero
                )}. Please """
                "specify the full path "
                "from one of the root entities to the target "
                "attribute. "
            )
E           sqlalchemy.exc.ArgumentError: Mapped class aliased(HaloLink) does not apply to any of the root entities in this query, e.g. Mapper[SimulationObjectBase(halos)]. Please specify the full path from one of the root entities to the target attribute.

../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:1618: ArgumentError
______________________________________________________________________ test_redirection_cascade_efficiency _______________________________________________________________________

    def test_redirection_cascade_efficiency():
        h = tangos.get_halo("sim/ts3/1")
        with testing.SqlExecutionTracker(db.core.get_default_engine()) as track:
>           h.calculate_for_progenitors("my_BH('hole_spin').test_array")

test_property_gathering.py:244: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../tangos/core/halo.py:391: in calculate_for_progenitors
    return self.calculate_for_descendants(*plist, **kwargs)
../tangos/core/halo.py:379: in calculate_for_descendants
    results = query.all()
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/query.py:2590: in all
    return self._iter().all()  # type: ignore
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/query.py:2730: in _iter
    result: Union[ScalarResult[_T], Result[_T]] = self.session.execute(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/session.py:2081: in execute
    return self._execute_internal(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/session.py:1976: in _execute_internal
    result: Result[Any] = compile_state_cls.orm_execute_statement(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/context.py:250: in orm_execute_statement
    result = conn.execute(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/engine/base.py:1414: in execute
    return meth(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/elements.py:487: in _execute_on_connection
    return connection._execute_clauseelement(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/engine/base.py:1630: in _execute_clauseelement
    compiled_sql, extracted_params, cache_hit = elem._compile_w_cache(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/elements.py:652: in _compile_w_cache
    compiled_sql = self._compiler(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/elements.py:288: in _compiler
    return dialect.statement_compiler(dialect, self, **kw)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:1075: in __init__
    Compiled.__init__(self, dialect, statement, **kwargs)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:639: in __init__
    self.string = self.process(self.statement, **compile_kwargs)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:671: in process
    return obj._compiler_dispatch(self, **kwargs)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/visitors.py:143: in _compiler_dispatch
    return meth(self, **kw)  # type: ignore  # noqa: E501
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/compiler.py:3949: in visit_select
    compile_state = select_stmt._compile_state_factory(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/base.py:641: in create_for_statement
    return klass.create_for_statement(statement, compiler, **kw)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/context.py:1012: in create_for_statement
    opt.process_compile_state(self)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:929: in process_compile_state
    self._process(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:1151: in _process
    loader.process_compile_state(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:1699: in process_compile_state
    keys = self._prepare_for_compile_state(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:2070: in _prepare_for_compile_state
    self._raise_for_no_match(parent_loader, mapper_entities)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.orm.strategy_options._AttributeStrategyLoad object at 0x1765149a0>, parent_loader = <sqlalchemy.orm.strategy_options.Load object at 0x1770de4c0>
mapper_entities = [<sqlalchemy.orm.context._MapperEntity object at 0x176502b30>]

    def _raise_for_no_match(self, parent_loader, mapper_entities):
        path = parent_loader.path

        found_entities = False
        for ent in mapper_entities:
            ezero = ent.entity_zero
            if ezero:
                found_entities = True
                break

        if not found_entities:
            raise sa_exc.ArgumentError(
                "Query has only expression-based entities; "
                f"attribute loader options for {path[0]} can't "
                "be applied here."
            )
        else:
>           raise sa_exc.ArgumentError(
                f"Mapped class {path[0]} does not apply to any of the "
                f"root entities in this query, e.g. "
                f"""{
                    ", ".join(str(x.entity_zero)
                    for x in mapper_entities if x.entity_zero
                )}. Please """
                "specify the full path "
                "from one of the root entities to the target "
                "attribute. "
            )
E           sqlalchemy.exc.ArgumentError: Mapped class aliased(HaloLink) does not apply to any of the root entities in this query, e.g. Mapper[SimulationObjectBase(halos)]. Please specify the full path from one of the root entities to the target attribute.

../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/strategy_options.py:1618: ArgumentError
______________________________________________________________________________________ test ______________________________________________________________________________________

    def test():
        # Before cleaning: we have two properties for halo 1
        # and one property for halo 2 and others
        halo = tangos.get_halo(1)
        assert halo["Mvir"] == [-2., -1., 1.]
        for ihalo in range(2, 10):
            halo = tangos.get_halo(ihalo)
            assert halo["Mvir"] == ihalo

        # We also have five links for halo 1 and one for halo 2
        assert tangos.get_halo(1).links.count() == 5
        assert tangos.get_halo(2).links.count() == 1
        # Only 4 links in halo 1 are maximally unique
        quads = [[l.halo_from.id, l.halo_to.id, l.weight, l.relation_id] for l in tangos.get_halo(1).all_links]
        assert len(np.unique(quads, axis=0)) == 4
        # And 3 links are unique by name, halo from and to
        triplets = [[l.halo_from.id, l.halo_to.id, l.relation_id] for l in tangos.get_halo(1).all_links]
        assert len(np.unique(triplets, axis=0)) == 3

        # Let's cleanup
>       remove_duplicates(None)

test_remove_duplicate.py:81: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../tangos/scripts/manager.py:199: in remove_duplicates
    count = session.execute(dedent("""
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/session.py:2081: in execute
    return self._execute_internal(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/orm/session.py:1894: in _execute_internal
    statement = coercions.expect(roles.StatementRole, statement)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/coercions.py:405: in expect
    resolved = impl._literal_coercion(
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/coercions.py:629: in _literal_coercion
    return self._text_coercion(element, argname, **kw)
../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/coercions.py:622: in _text_coercion
    return _no_text_coercion(element, argname)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

element = '\nDELETE FROM haloproperties\nWHERE id NOT IN (\n    SELECT * FROM (\n        SELECT MAX(id)\n        FROM haloproperties\n        GROUP BY halo_id, name_id\n    ) as t\n)\n'
argname = None, exc_cls = <class 'sqlalchemy.exc.ArgumentError'>, extra = None, err = None

    def _no_text_coercion(
        element: Any,
        argname: Optional[str] = None,
        exc_cls: Type[exc.SQLAlchemyError] = exc.ArgumentError,
        extra: Optional[str] = None,
        err: Optional[Exception] = None,
    ) -> NoReturn:
>       raise exc_cls(
            "%(extra)sTextual SQL expression %(expr)r %(argname)sshould be "
            "explicitly declared as text(%(expr)r)"
            % {
                "expr": util.ellipses_string(element),
                "argname": "for argument %s" % (argname,) if argname else "",
                "extra": "%s " % extra if extra else "",
            }
        ) from err
E       sqlalchemy.exc.ArgumentError: Textual SQL expression '\nDELETE FROM haloproperti...' should be explicitly declared as text('\nDELETE FROM haloproperti...')

../../../.python3_base/lib/python3.9/site-packages/SQLAlchemy-2.0.0b3-py3.9-macosx-10.9-universal2.egg/sqlalchemy/sql/coercions.py:592: ArgumentError
================================================================================ warnings summary ================================================================================
tests/test_ahf_trees.py: 12 warnings
tests/test_simulation_outputs.py: 30 warnings
tests/test_tracking.py: 24 warnings
  /Users/mrey/.python3_base/lib/python3.9/site-packages/pynbody/snapshot/tipsy.py:871: DeprecationWarning: The binary mode of fromstring is deprecated, as it behaves surprisingly on unicode inputs. Use frombuffer instead
    loadblock = lambda count: np.fromstring(

tests/test_ahf_trees.py: 3 warnings
tests/test_simulation_outputs.py: 6 warnings
tests/test_tracking.py: 3 warnings
  /Users/mrey/.python3_base/lib/python3.9/site-packages/pynbody/snapshot/tipsy.py:207: DeprecationWarning: The binary mode of fromstring is deprecated, as it behaves surprisingly on unicode inputs. Use frombuffer instead
    buf = np.fromstring(f.read(st_len * readlen), dtype=dtype)

tests/test_consistent_trees.py::test_property_import
tests/test_consistent_trees.py::test_property_import
tests/test_consistent_trees.py::test_property_import
tests/test_consistent_trees.py::test_property_import
tests/test_consistent_trees.py::test_property_import
tests/test_consistent_trees.py::test_property_import
tests/test_consistent_trees.py::test_property_import
tests/test_consistent_trees.py::test_property_import
  /Users/mrey/.python3_base/lib/python3.9/site-packages/pynbody/halo/rockstar.py:246: DeprecationWarning: The binary mode of fromstring is deprecated, as it behaves surprisingly on unicode inputs. Use frombuffer instead
    self._head = np.fromstring(f.read(self.head_type.itemsize),

tests/test_consistent_trees.py::test_property_import
  /Users/mrey/.python3_base/lib/python3.9/site-packages/pynbody/array.py:353: RuntimeWarning: invalid value encountered in divide
    return np.ndarray.__truediv__(self, rhs)

tests/test_import.py: 46 warnings
  /Users/mrey/Documents/tangos/tangos/testing/db_diff.py:97: LegacyAPIWarning: The Query.with_parent() method is considered legacy as of the 1.x series of SQLAlchemy and becomes a legacy construct in 2.0. Use the with_parent() standalone construct. (deprecated since: 2.0) (Background on SQLAlchemy 2.0 at: https://sqlalche.me/e/b8d9)
    return object_session(parent).query(core.HaloProperty).with_parent(parent, type(parent).all_properties).\

tests/test_import.py: 46 warnings
  /Users/mrey/Documents/tangos/tangos/testing/db_diff.py:93: LegacyAPIWarning: The Query.with_parent() method is considered legacy as of the 1.x series of SQLAlchemy and becomes a legacy construct in 2.0. Use the with_parent() standalone construct. (deprecated since: 2.0) (Background on SQLAlchemy 2.0 at: https://sqlalche.me/e/b8d9)
    return object_session(parent).query(core.HaloLink).with_parent(parent, type(parent).all_links).\

tests/test_live_calculation.py::test_property_redirection
tests/test_live_calculation.py::test_function_after_property_redirection
tests/test_live_calculation.py::test_calculate_array
tests/test_property_gathering.py::test_gather_linked_property
  /Users/mrey/Documents/tangos/tangos/live_calculation/__init__.py:616: RuntimeWarning: More than one relation for target 'BH' has been found. Picking the first.
    warnings.warn("More than one relation for target %r has been found. Picking the first."%str(self.locator), RuntimeWarning)

tests/test_live_calculation_link_syntax.py::test_ambiguous_link_made_explicit
tests/test_live_calculation_link_syntax.py::test_link_returned_halo_is_valid
tests/test_live_calculation_link_syntax.py::test_link_can_be_used_within_calculation
tests/test_live_calculation_link_syntax.py::test_link_returned_halo_is_usable
tests/test_live_calculation_link_syntax.py::test_multi_calculation_link_returned_halo_is_usable
tests/test_live_calculation_link_syntax.py::test_missing_link
  /Users/mrey/Documents/tangos/tangos/live_calculation/__init__.py:616: RuntimeWarning: More than one relation for target 'testlink' has been found. Picking the first.
    warnings.warn("More than one relation for target %r has been found. Picking the first."%str(self.locator), RuntimeWarning)

tests/test_pynbody_server.py::test_get_array
tests/test_pynbody_server.py::test_simsnap_arrays
tests/test_pynbody_server.py::test_halo_array
tests/test_pynbody_server.py::test_remote_file_index
tests/test_pynbody_server.py::test_lazy_evaluation_is_local
tests/test_pynbody_server.py::test_underlying_class
tests/test_pynbody_server.py::test_correct_object_loading
  /Users/mrey/Documents/tangos/tangos/parallel_tasks/backends/multiprocessing.py:137: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
    elif message[0]=='error':

tests/test_simulation_outputs.py::test_get_deprecated_handler
  /Users/mrey/Documents/tangos/tangos/input_handlers/__init__.py:197: DeprecationWarning: The database has stored the handler name as 'pynbody.ChangaOutputSetHandler'; automatically translating this to the new name 'pynbody.ChangaInputHandler'
    warnings.warn("The database has stored the handler name as %r; automatically translating this to the new name %r"%(handler, new_handler),

tests/test_simulation_outputs.py: 9 warnings
tests/test_tracking.py: 18 warnings
  /Users/mrey/.python3_base/lib/python3.9/site-packages/pynbody/snapshot/__init__.py:263: DeprecationWarning: `np.bool` is a deprecated alias for the builtin `bool`. To silence this warning, use `bool` by itself. Doing this will not modify any behavior and is safe. If you specifically wanted the numpy scalar type, use `np.bool_` here.
  Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations
    elif isinstance(i, np.ndarray) and np.issubdtype(np.bool, i.dtype):

tests/test_stat_files.py::test_import_properties_is_only_numeric_or_array
  /Users/mrey/Documents/tangos/tests/test_stat_files.py:138: DeprecationWarning: `np.int` is a deprecated alias for the builtin `int`. To silence this warning, use `int` by itself. Doing this will not modify any behavior and is safe. When replacing `np.int`, you may wish to use e.g. `np.int64` or `np.int32` to specify the precision. If you wish to review your current use, check the release note link for additional information.
  Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations
    assert property.data.dtype == np.int

tests/test_stat_files.py::test_import_properties_is_only_numeric_or_array
  /Users/mrey/Documents/tangos/tests/test_stat_files.py:143: DeprecationWarning: Converting `np.inexact` or `np.floating` to a dtype is deprecated. The current result is `float64` which is not strictly correct.
    assert property.data.dtype == np.floating

tests/test_web.py::test_root_page
tests/test_web.py::test_root_page
tests/test_web.py::test_simulation_page
tests/test_web.py::test_simulation_page
tests/test_web.py::test_timestep_page
tests/test_web.py::test_timestep_page
tests/test_web.py::test_halo_page
tests/test_web.py::test_halo_page
  /Users/mrey/.python3_base/lib/python3.9/site-packages/pkg_resources/__init__.py:1135: DeprecationWarning: Use of .. or absolute path in a resource path is not allowed and will raise exceptions in a future release.
    return get_provider(package_or_requirement).get_resource_filename(

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
============================================================================ short test summary info =============================================================================
FAILED test_live_calculation.py::test_liveproperty_requiring_redirection - sqlalchemy.exc.ArgumentError: Mapped class aliased(HaloLink) does not apply to any of the root entities in this query, e.g. Mapper[SimulationObjectBase(halos)]. Please speci...
FAILED test_property_gathering.py::test_gather_linked_property_with_fn - sqlalchemy.exc.ArgumentError: Mapped class aliased(HaloLink) does not apply to any of the root entities in this query, e.g. Mapper[SimulationObjectBase(halos)]. Please speci...
FAILED test_property_gathering.py::test_path_factorisation - sqlalchemy.exc.ArgumentError: Mapped class aliased(HaloLink) does not apply to any of the root entities in this query, e.g. Mapper[SimulationObjectBase(halos)]. Please speci...
FAILED test_property_gathering.py::test_single_quotes - sqlalchemy.exc.ArgumentError: Mapped class aliased(HaloLink) does not apply to any of the root entities in this query, e.g. Mapper[SimulationObjectBase(halos)]. Please speci...
FAILED test_property_gathering.py::test_redirection_cascade_closes_connections - sqlalchemy.exc.ArgumentError: Mapped class aliased(HaloLink) does not apply to any of the root entities in this query, e.g. Mapper[SimulationObjectBase(halos)]. Please speci...
FAILED test_property_gathering.py::test_redirection_cascade_efficiency - sqlalchemy.exc.ArgumentError: Mapped class aliased(HaloLink) does not apply to any of the root entities in this query, e.g. Mapper[SimulationObjectBase(halos)]. Please speci...
FAILED test_remove_duplicate.py::test - sqlalchemy.exc.ArgumentError: Textual SQL expression '\nDELETE FROM haloproperti...' should be explicitly declared as text('\nDELETE FROM haloproperti...')
================================================================== 7 failed, 246 passed, 234 warnings in 53.62s ==================================================================
apontzen commented 1 year ago

See #214 - could you confirm this now works on your system?